Skip to content
Advertisement

Unable to exit while loop after reading information written to pipe

TLDR: You have to close the write end of all pipes in all children. The read will detect EOF only if no process has the write end still open. Credits to @Bodo

As part of an assignment for an operating systems course, I’m trying to read lines from a file which is in the format of x operand y and distribute the lines to different child processes so that each one can take those lines as input and conduct calculations and write it to one output file.

I feel like I’m almost there by getting the right results, but my code seems to lead to an endless while loop after reading all of the written lines to the read end of a pipe.

Here’s the relevant code snippet

JavaScript

This is the output that I am getting, which seemingly gets stuck in an infinite while loop as the process won’t terminate. Also, the value of return values of read: should either be 22 or 23 based on the particular input file that I am using, but I don’t know why it is incrementing for particular subsequent child processes. None of the child processes seem to be able to exit the while loop as this printf("exited while loop and reached end of child process %dn", mypid); doesn’t seem to be executed. My understanding is that if a pipe has been read, the return value will be the byte size of the line read, and if it reaches EOF or an error, the return value is 0 or -1, respectively.

JavaScript

I would appreciate any insight for a silly mistake I might be making. Thanks!

Advertisement

Answer

There are several problems in the code.

Unfortunately I cannot compile it and fix the errors because it is incomplete.

  1. You cannot define arrays with a size that is not constant like this.

    JavaScript

    I would expect the compiler to show a warning at this line.
    You should either use dynamic allocation (malloc) or statically allocate the arrays with a maximum size and check that proc is not greater than the maximum.

  2. You have to close the write end of all pipes in all children. The read will detect EOF only if no process has the write end still open.

  3. Instead of

    JavaScript

    I suggest

    JavaScript
  4. Instead of

    JavaScript

    it should be

    JavaScript

    because pid < 0 is an error.

  5. Instead of

    JavaScript

    use

    JavaScript

    With break; the child would continue with the code after the for loop that would read the file and write to the pipes when child_work returns.

  6. It is not guaranteed that every child will get its turn to read from the pipe before the parent writes the next data, so it may get two or more messages in a single read. In real applications you should also be prepared to handle incomplete read or write calls and to continue writing/reading the remaining data with additional read or write calls.

    I think the easiest way to handle partial read or write would be to use buffered IO. You can use fdopen with the wrtite file descriptor or the read file descriptor of the pipe and write/read the data as a line of text terminated with a newline using e.g. fprintf or fgets respectively.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement