The problem is that you did not close pfd[1]
in process 3, add close(pfd[1]);
after case 0 in that process 3 will fix it.
In process 3, that cat
will read from pfd[0]
, however there are four pfd[1]
in those processes:
process 0
this is the main process,
pfd[1]
in this process will be closed by that close beforewait()
.process 1
after
ls
finished,pfd[1]
in this process will be closed automatically by the operating system.process 2
pfd[1]
has been closed before executingcat
.process 3
pfd[1]
is open in this process whilewc
is running, and this is what happened at that moment:- in process 2,
cat
tries to readpfd[0]
for data frompfd[1]
- in process 3,
wc
tries to readpfd2[0]
for data frompfd2[1]
- because
pdf[1]
still open in process 3, and nothing will be written to it, reading frompfd[0]
in process 2 (cat) will wait forever - because
cat
in process 3 still alive, reading frompfd2[0]
in process 3 (wc) will wait (forever)
- in process 2,
As you can see, you have a deadlock between process 2 (cat) and process 3 (wc) because of file descriptor leak. To break this deadlock, you just need to close pfd[1]
in process 3 before you run wc
, after that:
cat
in process 2 will exit afterls
in process 1 exits, because there is nothing left for it (cat) to read- after
cat
in process 2 exits,wc
in process 3 will also exit, because there is nothing left for it (wc) to read - after that, the main process (parent process) will exit, and the program will finish.
It is possible that there are more than one write ends for the read end of a pipe, unless all these write ends are closed, end-of-file will not be delivered to the read end, and the reader will just wait for more data to come. If there is nothing to come, that reader will wait forever.