I have a program/project that forks and execs, and the processes that it creates communicate through pipes. I ran into a problem, where process A was waiting on process B, but process B was also waiting on process A. To illustrate the problem, I made a small program that sets up a pipe, then forks. The parent is supposed to send the child 2 messages. The parent sends them, then waits for the child to terminate. The child reads message1, but does not see message2, so it waits. The reason why is that it gets both messages at once. It sees message1 but not message2 because the data read is message1,0,message2,0: the read command gets everything at the pipe at that moment. In processing the data read we might (as in this case) assume that the message data ends with the first null character (0). The fix is to approach the "read" command differently, and look for message 2 in the string already read if the length read and the string's length (from strlen) are different. Here is the program that illustrates the problem. macbook:Desktop> ./pipe_deadlock parent: Fork() did not return 0, ppid is 2667, pid is 51812 parent: wrote message1 to the pipe. I am the child. child: Fork() returned 0, ppid is 51812, and pid is 51813 child: Now wait 2 seconds. parent: wrote message2 to the pipe. parent: wait on child to terminate child: I am expecting message1 from the pipe. child: read message1 from pipe: hello child: I am expecting message2 from the pipe. ^C Control-C was used to stop, otherwise it would wait forever. The source code is below. /* A simple pipe example, loosely based on "pipe_example.c" from Paul Krzyzanowski, and what I remember from the Glass/Ables book. This program shows how deadlock can arise when using pipes. -Michael Weeks */ #include #include #include #include // for fork, sleep #include // for wait #define SIZE 100 int main (int argc, char* argv[]) { int fd1[2]; pipe(fd1); // Fork this process into 2 processes. if (fork() != 0) { int childPid, status; // This must be the parent process. printf("parent: Fork() did not return 0, ppid is %d, pid is %d\n", getppid(), getpid()); // close the input part of the pipe close(fd1[0]); // Write a simple message to the pipe. printf("parent: wrote message1 to the pipe.\n"); write(fd1[1], "hello", 6); // include null char usleep(250000); // wait 1/4 second printf("parent: wrote message2 to the pipe.\n"); write(fd1[1], "there", 6); printf("parent: wait on child to terminate\n"); childPid = wait (&status); printf("A child with PID %d terminated with exit code %d\n", childPid, status >> 8); printf("parent: returning\n"); } else { printf("I am the child.\n"); printf("child: Fork() returned 0, ppid is %d, and pid is %d\n", getppid(), getpid()); // close the output part of the pipe close(fd1[1]); int num; char mybuf[SIZE]; printf("child: Now wait 2 seconds.\n"); sleep(2); // Read a simple message from the pipe. printf("child: I am expecting message1 from the pipe. \n"); num = read(fd1[0], mybuf, SIZE); printf("child: read message1 from pipe: \n"); printf("%s\n", mybuf); printf("child: I am expecting message2 from the pipe. \n"); num = read(fd1[0], mybuf, SIZE); printf("child: read message2 from pipe: \n"); printf("%s\n", mybuf); printf("child: returning\n"); } return 0; }