When the following code runs, I understand the parent and child both will run in parallel immediately after fork() is called.
#include
I recognise that this might not exactly answer the question, but it may serve to shed some light into what is happening:
if (!fork()) {
printf(" CHILD: writing to the pipe\n");
write(pfds[1], "test", 5);
printf(" CHILD: exiting\n");
exit(0);
} else {
printf("PARENT: reading from pipe\n");
read(pfds[0], buf, 5);
printf("PARENT: read \"%s\"\n", buf);
wait(NULL);
}
After fork has been executed, the parent process continues to run, which then proceeds to the else statement, and executes the printf function. After that it attempts to read from the pipe, but it blocks because there is no data in the pipe. That's right, read()
blocks when it attempts to read from a pipe without data.
Documentation that serves to prove this is available. From the xv6 documentation:
If no data is available, a read on a pipe waits for either data to be written or all file descriptors referring to the write end to be closed; in the latter case, read will re- turn 0, just as if the end of a data file had been reached.
And while xv6 may not be Linux, it serves as a design guide to UNIX. If you don't consider this valid enough, then the linux Man pages on pipes can shed some light:
If a process attempts to read from an empty pipe, then read(2) will block until data is available. If a process attempts to write to a full pipe (see below), then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete. Nonblocking I/O is possible by using the fcntl(2) F_SETFL operation to enable the O_NONBLOCK open file status flag.
After that, control is passed to the child, which proceeds to execute its version of the printf()
function, write()
s to the pipe, and then prints an exiting message, finally exiting after that.
When the child has exited, control is again passed to the parent process, which finds read()
on the pipe to be able to read data, which allows it to finish what its work.
So as far as the
In parallel
part is concerned, it doesn't seem to be in parallel exactly. It's serial, it's just very fast for us to notice that it's done in a serial order of execution.
Apparently whatever scheduler you're running decides, and it can vary.
I can say from experience that if you assume that one of the two processes always runs first, you will introduce some very subtle race conditions. Either synchronize on something, like a special message on the pipe, or don't assume that either one runs first.