[SOLVED] Why is my C program output not in the same order as when I redirect it to a file ?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Why is my C program output not in the same order as when I redirect it to a file ?
It's a multi-threading program synchronized with semaphore. According to my knowledge, those three thread should print one by one, at least in this way.
And if I redirect it to a file, it seems the lines are organized by thread and the print line in father thread is repeated 3 times ???
I am a rookie in multi-threading programming. please help me.
this is not multithreading, but multitasking. -pthread is useless here (actually it is required because of the semaphore, but it is still not a multithreaded app).
(Multithreading) multitasking means the three children will run parallel, therefore the output can be mixed. And occasionally they are not mixed, it just depends on the kernel and the execution.
this is not multithreading, but multitasking. -pthread is useless here (actually it is required because of the semaphore, but it is still not a multithreaded app).
(Multithreading) multitasking means the three children will run parallel, therefore the output can be mixed. And occasionally they are not mixed, it just depends on the kernel and the execution.
Thx for the reply. I noticed the lines are mixed in a different way between executions but are in different dimensions: In terminal every line is mixed. In the file each task’s output is mixed but lines from different tasks are not.
Also, why is the line of printf in the shared code have four outputs in a file but one in a terminal?
I guess it depends on the load of the system and other resources (like ram, cache). In general the order of those output lines is unpredictable. It also may depend on the internal buffers used by the app (for example printf) and the timings (for example if fork needs more time than the full loop).
I guess it depends on the load of the system and other resources (like ram, cache). In general the order of those output lines is unpredictable. It also may depend on the internal buffers used by the app (for example printf) and the timings (for example if fork needs more time than the full loop).
It's a multi-threading program synchronized with semaphore. According to my knowledge, those three thread should print one by one, at least in this way.
And if I redirect it to a file, it seems the lines are organized by thread and the print line in father thread is repeated 3 times ???
This is almost certainly due to stdio buffering. Output to a terminal is by default line-buffered, i.e., the buffer is flushed after each newline character. Output to a file defaults to block-buffered, where the buffer is flushed whenever a full block (typically 4K) is collected.
You can use the setlinebuf() call to force an output stream to be line-buffered regardless of the device. See `man serlinebuf` for details.
You have "forked" several different processes, all of which are producing output that is "directed to the terminal." However, because they are "several different processes," each of them has its own STDIN, STDERR, STDOUT streams, to which each of them are writing independently. Yes, the various outputs are ultimately being gathered to the same physical destination – whether it be a terminal screen or a disk file – but it is unpredictable as to the order in which the various events might occur. (Likewise, the possibility of "buffering" which you also have no control over.)
I note that your source-code is peppered with wait() calls, as though you were trying to use these to achieve the "expected" output.
Your rule-of-thumb must be that the order-of-events of multitasking or even multithreaded operations is "UNPREDICTABLE."
Thanks for replying. I kind of understand that it's the buffering cause the differences.
When I use the setlinebuf() call, the output in the file behaves the same as the terminal.
There's still one thing I'm confused about.
I think the buffering should only affect the order of lines. But the “printf(”init\n”);” prints 1 line when line-buffered, however, 3 lines when block-buffered. Is it a feature of Linux (merging the duplicate lines printed by the shared part of several tasks when line-buffered)?
But the “printf(”init\n”);” prints 1 line when line-buffered, however, 3 lines when block-buffered. Is it a feature of Linux (merging the duplicate lines printed by the shared part of several tasks when line-buffered)?
That should not be happening. Pipe the output through "hexdump -c", and/or run "hexdump -c" on the output file, to see exactly the characters being sent.
That should not be happening. Pipe the output through "hexdump -c", and/or run "hexdump -c" on the output file, to see exactly the characters being sent.
This may be due to my ignorance, but I don’t understand how does that help?
As you can see, there are 3 "init\n"(not child* init) in a (block-buffered)file but 1 "init\n" in a terminal.
In other words, the total numbers of rows are different.
Also, is my semaphore code completely useless? I haven't noticed any of semaphore's functions behaving at runtime.
the 3 init lines are tricky, the forked processes may inherit the content of the buffer too (because that was not flushed).
From the other hand the semaphores are completely useless. But in some cases (when you have something else in between sem_wait and sem_post) it can be useful.
the 3 init lines are tricky, the forked processes may inherit the content of the buffer too (because that was not flushed).
From the other hand the semaphores are completely useless. But in some cases (when you have something else in between sem_wait and sem_post) it can be useful.
I thought that placing the “printf” between the sem_wait() and sem_post() would make 3 children to be printing in order.
For example, when child1 runs into printf, child 2 and child 3 will be waiting for releasing of semaphore, which will cause child 1 to not print sequentially. If I was right, the output should be like:
child1 write
child2 write
child3 write
or
child1 write
child3 write
child2 write
or something similar
but not
child 1 write
child 1 write
child 1 write
but they are obviously not
So, where is the error in my description?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.