The output can be in any order, with the only restriction that, for each process, the first statement (the first printf()
) should be executed before the second. The actual output normally shows like some processes have some kind of preference, but this is a consequence of the way the kernel arranges to schedule them, and the actual number of cores, and contexts switches each codre is allowed to do. You can observe a completely different approach, if you redirect stdout
to a file, or pipe it to another process, as in this case, stdout
turns into total buffering and every process complete output will happen together (as the write(2)
system call is not done, but until the process calls exit(2)
after returning of main()
, and then the full buffer is output in one system call. But this is related on how stdout
flushes it's buffers (on a tty output device it flushes output at each \n
char, while on a file or a pipe, it flushes only if buffer gets completely full ---which never happens with the amount of data you are printing) and not on scheduling behaviour of the kernel.
In your case, the eight processes just block at the first write(2)
(well, the eight not, only seven, the other got the lock and is executing the write system call) of the first process that calls printf(3)
, as while the write is being performed (in the system), the output device inode is locked in the kernel, and no one can enter to write(2)
on a locked inode, so is is very probable that, when the process returns from write(2)
it starts it's second write(2)
(in the second call to printf(3)
, and getting the lock again, if no other process has had a chance to get the lock in the time between both system calls). But there's no reason for the order to be different, or in a loadad system, for the kernel to decide to allow other different process to run before the one that was running before. Think that a process is not preempted, but only when returning from kernel mode, and only if other process has acquired more priority (something that happens slowly) and is free to run (this will probably not happen to the other processes that are blocked to get the inode of the output device, and this requires them to be scheduled)
The only case in which interspersed output can be observed, is that, while the process with the lock is about to return to user mode, the kernel schedules one of the other processes that have been awaken from the inode lock, and gets the lock, but if this process is not preempted (in a multi processor system) it is very difficult for that processor to get the inode lock before the one that was running already (there's a very small window for that to happen, but it can be possible)
This is the output I get (on FreeBSD, with a CoreDuo processor ---two cores, I've modified your example to show the pids of the authors of the printf()
calls to show that there's a big chance that the process that print):
$ pru
[33781]: First print statement.
[33782]: First print statement.
[33787]: First print statement.
[33787]: Second print statement.
[33784]: First print statement.
[33784]: Second print statement.
[33788]: First print statement.
[33788]: Second print statement.
[33785]: First print statement.
[33785]: Second print statement.
[33786]: First print statement.
[33786]: Second print statement.
[33783]: First print statement.
[33783]: Second print statement.
[33782]: Second print statement.
[33781]: Second print statement.
$ _