martin@mwtech.UUCP (Martin Weitzel) (07/04/90)
In article <3640@zorba.Tynan.COM> idall@augean.ua.OZ.AU (Ian Dall) writes: >In article <3589@zorba.Tynan.COM> machala@vlsic2.csc.ti.com (Chuck Machala) writes: >> >> I have run into a problem with UNIX pipes deadlocking. Seems there's >> a bug in pipe. MAN says "Should more than 4096 bytes be neccessary >> in any pipe among a loop of processes, deadlock will occur." That's >> what we have, a loop of processes which deadlock; however, it dead- >> locks with NO bytes in the pipe. If you define "deadlock" as the situation where several processes wait for some event that can only be generated by someone who is allready waiting, many of such situations may arise if processes are connected thru pipelines. Especially with named pipes, the order of opening two pipes for two way communication is crucial, because the first open may have to wait for the partner (also know as "rendevouz principle"). Hence two processes that want a two-way path using two named pipes must do the open just in the opposite order (one must open the read side first, the other the write side - of course, with regard to the *name* of the pipes, they must use the same order.) An other famous example is a pipe create in the conventional manner by the pipe system call or a named pipe opend for read and write. (BTW: Such an open would not have to wait, which seems natural beacause a read end and a write end are immediatly available, but IMHO this feature is undocumented.) If the process now tries to read until end of file but "forgets" to close its own write side it will never see end of file, because there's still a potential writer - the reading process! If more than two process communicate thru pipes, there should be a *very* thorough design to prevent the chance for casual deadlocks. Bascially, there are two techniques: The first is acquiring and releasing all resources in exactly the same order. If this is done by all concurrently running processes, it's not so hard to prove that there can occur no deadlocks. The second approach is to use timeouts. (Hint: You can add timeouts in a very clean way thru daemon process, which now and then write something to the pipes. Of course, the reading processes must be able to sort out the dummy messages.) Now lets come to this: >I have seen this. > >mknod PIPE1 p >cat ~/.login | tee PIPE1 | wc | cat - PIPE1 > The reason for the deadlock is relatively easy to detect here. Start this program in the background (add an & at the end) and then try ">PIPE1" and "<PIPE1". The first will do nothing, but act as a possible "writer" for a short moment, the second will do similar but as "reader". You will note that the first will also hang, but the second will unlock the whole thing. So it's obvious that the deadlock in the above example was caused by a writer that had non potentioal reader. A little thought will confirm this. Before "tee" will write any bytes to its output, it must open PIPE1 - and wait for a reader. On the other side, "cat" waits for EOF from its standard input. Because there is a possible writer, "wc", "cat" can not proceed and open PIPE1 for reading. Hence there's a deadlock. The smallest failing case where this condition occurs is tee PIPE1 | cat - PIPE1 so if you want to play a little bit and look how you can this bring to run, use the above one. (Playing a litte bit with named pipes at shell level before using them in programs may pay later, when you design your programs.) -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
dave@labtam.oz.au (David Taylor) (07/14/90)
idall@augean.ua.OZ.AU (Ian Dall) writes: >mknod PIPE1 p >cat ~/.login | tee PIPE1 | wc | cat - PIPE1 >Should work. My .login is around 600 bytes. It does work on a vanilla >system V.2.2 box I have, but it doesn't work on a Sun4 running SunOs 4. Shouldn't work ... classic deadlock situation. cat can't start reading PIPE1 until it has finished reading standard input which cn't occur until wc finishes, which can't occur until tee finished, which can't occur until someone (cat) is willing to read PIPE1. -- .. Dave T.
peter@ficc.ferranti.com (Peter da Silva) (10/10/90)
The problem is that sometimes people want a "bag" they can shove stuff in at one and, and pull stuff out at the other. A UNIX fifo doesn't fit this model, because the "bag" empties itself when closed, and won't let you stuff things in unless someone's handy to pull them out again. Anyone ever implemented such a beast under UNIX (some variants of pipes on the Amiga work this way)? -- Peter da Silva. `-_-' +1 713 274 5180. <peter@ficc.ferranti.com>