0

I have some doubts about pipes appreciate help if anyone knows

A pipe can be shared by multiple processes simultaneously allowing these processes exchanging "messages" to each other. When there are multiple read processes of the same pipe can all read the same message (sent only once and not multiple copies)?

In a multi-threaded environment it is possible that a message sent by a process is corrupted when writing to the pipe?

thanks for listening

user2989745
  • 149
  • 1
  • 3
  • 12
  • possible duplicate of [Named Pipes (FIFOs) on Unix with multiple readers](http://stackoverflow.com/questions/1634580/named-pipes-fifos-on-unix-with-multiple-readers) – jweyrich Dec 15 '13 at 16:58
  • the first question yes, ok only one picks up the answer, but the second question does not even know the answer. The issue of mult-threading ..... – user2989745 Dec 15 '13 at 17:12
  • If the message is long enough and sent in multiple writes, then yes it can be corrupted. – egur Dec 15 '13 at 17:26
  • why do you say that? Write can exist in several repeated information or lack of information, do not understand why several thread can corrupted the message? – user2989745 Dec 15 '13 at 17:38

1 Answers1

5

Stop thinking about "messages". The pipe accepts a sequence of bytes, and your application is entirely responsible for assigning any structure to the sequence. Each byte written to the pipe can be read exactly once, and not multiple times. If each write to the pipe is a fixed size and smaller than a system specified amount, then the write will be atomic and the data will not be "corrupted" (interleaved with other writes) during the write. However, if any of the readers are reading blocks of a different size, then data may be interleaved on the read end. (eg, a writer writes 64 bytes as one "message", but a reader reads 60 bytes from the pipe. The reader expecting a 64 byte sequence will then get 4 bytes from the tail of one and 60 from the start of another, and your data may appear "corrupted"). It is very easy to get "corrupted" data in a multi-threaded environment. It is possible to ensure that none of the writes are interleaved, but it can be difficult to get it right. Keep the messages small and of a fixed size, and make sure the are written with a single write system call (eg, do not use fprintf on a FILE* with the pipe as the underlying file descriptor.)

Note that I'm using the word "corrupted" in quotes throughout, because I believe you really mean interleaved. The byte sequence that you write will not be corrupt from the system's perspective. You may not get back what you expect, but that is not corruption of the data. Rather, it is a programming error.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • already thanks for the help. I think I understand the idea, when it can be read inconsistent data. The consistency of the data is not guaranteed. But even now, is irrelevant in this case have multiple thread or multiple processes right? This problem can happen when we have multiple processes or thread to read simultaneously without mutual exclusion. – user2989745 Dec 16 '13 at 16:19
  • If you have two threads, one that writes 'a','b' in two separate writes, and one that writes 'c','d' in two separate writes and you do not synchronize, then you might get any of: abcd, acbd, acdb, cdab, cadb, or cdab. The operating system guarantees that the data read from the pipe is read in the same order it was written. But if thread 1 writes 'ab' in a single write and thread 2 writes 'cd' in a single write, you might get either 'abcd' or 'cdab'. The consistency is guaranteed, but atomicity is only guaranteed if writes are smaller that PIPE_BUF bytes. – William Pursell Dec 16 '13 at 16:52
  • Do you know how a reader knows when it has finished reading (message framing semantics)? For example if I wrote `a`, then `b`, then `c`. And then I ran `cat named_pipe`, it only returns `a` and then closes. How does it know that the "message" is terminated at `a` and not at the `abc`? Is it using a null character? A EOF character or something else? – CMCDragonkai May 27 '15 at 11:05
  • @CMCDragonkai it sounds like you are closing the pipe after each write. – William Pursell May 27 '15 at 13:20
  • Did you check the success of the writes? If you close a fifo, and re-open it, you should get all the data. But there is no message framing. If you successfully write 'a' and then 'b', it is no different than if you write 'ab', other than the fact that some other process may write interleaved data in the first case. – William Pursell May 27 '15 at 13:34
  • The writing process is just using `(echo "a" >> named_pipe &) && (echo "b" >> named_pipe &) && (echo "c" >> named_pipe &)`. I'm not really doing anything fancy. The pipe is on the file system. – CMCDragonkai May 28 '15 at 04:35
  • Using the shell command shown, I get different permutations of lines showing the letters 'abc' each time (That is, each pair "a\n" stays matched, but the order of the pairs is different, but I always see all 3 with bash 3.2.57 on Darwin 14.3.0) Which shell are you using, and what output do you get if you run `(echo a&) && (echo b&) && (echo c&)`? – William Pursell May 28 '15 at 10:58
  • If I simply add a sleep and run `( { sleep 10; echo b >> named_pipe& } )` the b goes away, so probably you are just triggering a race condition, – William Pursell May 28 '15 at 11:02