简体   繁体   中英

2 children write to pipe, parent reads from pipe in C

I've searched and searched to no avail, so I've finally come to ask for some help. My assignment involves (in C running on RedHat Linux) creating two child processes, each of which write characters for an arbitrary amount of iterations to a pipe. This pipe is shared with the parent process that created them. The parent reads from the pipe while the children still have characters to write to it. Once the children have exited and the pipe is empty, the parent(main) can then terminate.

Here is a quick & dirty example of the logic of the code I have written.

main()
{
      //create pipe

      fork(); //childA
      //writes to pipe 

      fork(); //childB
      //writes to pipe

      //parent reading
      while(condition) {
          //read from pipe + print chars to terminal
      }
}

Now, my question is regarding the condition of the while loop. I need to read when the children are blocked from writing due to a full pipe, but I cannot figure out what type of condition would allow me to do this. Any help would be absolutely amazing.

Is it a requirement that the pipe needs to be full when you read? Or is it simply a requirement that you keep reading from both children, even if one of the pipes is full so the child is blocked on writing?

I don't know of any standard way to tall if a pipe is full. You could try using the FIONREAD ioctl to determine how much data there is to read on the pipe, and compare that against PIPE_BUF , but that may not work properly if there is less than PIPE_BUF data in the pipe, but the child is doing a write that would put it over PIPE_BUF ; that call may block without filling up the pipe. I would not rely on this technique working.

The usual way to keep reading from two file descriptors, regardless of which one is ready, is to use the select system call. This allows you to wait until one or the other file descriptor has data available. This means that the parent process won't block trying to read from one child which doesn't have any data available, while the other child is blocking because its buffer is full.

edit : After re-reading your question, it sounds like there is actually only one pipe, that both children are writing to. Is that correct? Again, the question comes up about whether you are required to wait until the children are blocking. If the parent simply reads from the pipe, it will block until one of the children has written to the pipe; you don't need to do anything special.

If your assignment requires you to wait until the pipe is actually full, I'd be interested in seeing the exact wording, because I'm not sure why you would want to do that.

edit 2 : In response to your questions in the comment:

  1. Does the code for my parent process need to follow the code for my two child processes within the program?

    No, there is no requirement about the order of the code for the parent or child processes. In order to distinguish the code the parent runs from the code the children run, you check the return value of fork() . If the return value is 0, you are in the child process. If it is not, you are in the parent; if the return value is -1, then there was an error, if it's positive, it is the PID of the child process.

    So, you can write code like this:

     int pid = fork(); if (pid) { // in the parent, check if pid is -1 for errors } else { // in the child } 

    Or:

     int pid = fork(); if (pid == 0) { // in the child, do whatever you need to do and... exit(0); } // in the parent; since the child calls exit() above, control will never // reach here in the child. Or you could do an execl() in the child, which // replaces the current program with another one, so again, control will // never reach here within the child process. 
  2. How can I keep reading from the pipe until the two children terminate AND the pipe is empty?

    Just keep reading until read returns 0. read on the read end of the pipe will not return 0 until all processes have closed the write end of the pipe, and all data has been read out of the pipe. If something still has it open, but there is no data in the pipe, read will block until data is written to the pipe.

    One gotcha is to remember to close the write end of the pipe in the parent process before trying to read ; otherwise, when the parent tries to do a read after the children have finished, it will block waiting for it to close its own pipe.

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