简体   繁体   中英

Synchronize parent and child without semaphores

(no semaphores, or threading, just processes)

I want to read data from a file in parent and pass it to child through pipe. Suppose data in file is

Is
This
Possible?

now after reading " Is " through pipe

  1. How would child know that new data " This " has been passed and should be read
  2. What would be the terminating condition after reading " Possible? " through pipe, so that child can terminate after reading all the data Parent wanted to pass

(Doing it without using semaphores or threads, just plain processes ie forking)

Thanks in Advance

A parent writing to a file and the child reading from it would require the synchronization you're thinking of. That is, if parent has only written the 1st line and child has read it, but parent has not written line 2, child will get a premature EOF.

But, a pipe does not.

A pipe stays open until the parent/sender closes it [or child terminates]. So, the child can just read in a loop until it receives EOF.

The child will automatically block in the read if no data is available but will not get EOF prematurely. If you want, the child can do select(2) or poll(2) to check for data being available but I hardly think that's necessary.

The child will not get EOF until the parent has sent all the data and closed its end of the pipe.

So, no synchronization is needed.

On the other side, we may have a parent that sends lots of data quickly and the child is reading slowly (ie) falls behind a bit. Eventually, the [kernel] pipe buffer gets "full" and the parent write will block until the child has been able to "catch up" and drain some of the data. Thus, no data is "lost".

You can simply read a fixed amount of data using fairly ubiquitous read() or fread() API, and use the fact that these will either block until more data is available or signal end-of-file conditions. This is the most straightforward way to pipe data into child processes: the child simply reads from stdin like an ordinary file, until it encounters the 'end-of-file' condition.

Alternatively, for a more responsive/performant design (or when dealing with hardware that signals on file objects) you need:

  1. Enable support for nonblocking I/O
  2. Monitor your input file descriptor/handle (the read side of the pipe) using select() like API
  3. Integrate with an event loop (or write a simple one yourself)
  4. Be able to deal with unexpected amounts of data available.
  5. Be able to deal with errors from read() / fread() and friends, in particular EAGAIN .
  6. And be able to deal with end-of-file conditions.

Wiring this up means delving into OS specific APIs, but fortunately it's also a common enough task that plenty of toolkit libraries (eg libuv, Qt) exist and provide consistent abstraction/higher level API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM