0

Basically, I have multiple children generated by a for loop with fork(). Lets assume 5 children are generated. And the parent will send mathematical equations to the children one by one through a pipe (Totally 20 equations). And the children will calculate the result of the equation an output into a file.

However, the while loop doesn't seem to end even if all the equations have been calculated.

In the child:

while(read(pipes[procid][0], buf, MAIN_BUF_LEN) > 0){
    exp_readln(&exp, buf);//Change the string into Expression class
    result = exp_cal(&exp);//Calculate the result
    printf("Recieved: #%d %d %0.3f\n", procid, mypid, result);
    fprintf(outfileptr, "#%d %d %0.3f\n", procid, mypid, result);
    fflush(outfileptr);
}
printf("Exit loop\n");
close(pipes[procid][0]);
exit(0);

In the parent:

i = 0;
while (fd_readln(fileno(infileptr), buf, MAIN_BUF_LEN) > 0){
    printf("Sent %d: %s\n", i, buf);
    dprintf(pipes[i][1],"%s\n", buf);
    i = i + 1;
    if (i >= proc){
      i = 0;
    }
}

The expected result is that after a child received and processed all the equations, it will output the calculation result. And it did. However, it does not output the "Exit loop" statement, showing that the program stayed in the while loop even if there is no more data/equations coming through the pipe. So how should I fix this problem?

ceving
  • 21,900
  • 13
  • 104
  • 178
Programmer
  • 151
  • 1
  • 12
  • 1
    Did you close the writing end of the pipe in the parent when it finished writing to the file? – Trickzter Mar 28 '19 at 08:32
  • 2
    You have to make sure the writing end of the pipes is closed in all processes. As long as one process (even the child that is supposed to read from the other end) has the writing end open, the `read` will wait for data. I don't know if you are the same user or got the same task as in this question https://stackoverflow.com/q/55377897/10622916 – Bodo Mar 28 '19 at 08:37
  • Yes, I have closed all the reading end using a for loop after sending all equations to child, but it still have this problem: for (i = 0; i < proc; i++){ printf("Closed pipe:%d\n", i); close(pipes[i][1]); } – Programmer Mar 28 '19 at 08:41
  • I am not sure about that for loop closing all writing ends at the same time. You may follow the following advice for ipc if you like: 1. Create the pipe 2. Fork the process. 3.1 Directly close the reading end in parent since you want to write there. 3.2 Write to the pipe in the parent. 3.3 Close the write end of the pipe in the parent. 4.1 Directly close the write end in the child since you want to read there. 4.2 Read from the pipe in the child. 4.3 Close the read end of the pipe in the child. With this strategy ipc should work. – Trickzter Mar 28 '19 at 08:52
  • reading a pipe is blocking until the writing end is closed. You are closing the reading end (in the child after the while, which you can't get out) not the writing end (from the parent) – Meher Khiari Mar 28 '19 at 09:18
  • Ok thanks, so I need to put close(pipes[procid][1]); inside the while loop. But how do I check when all equation has been recieved in the loop? Since the number of equation can vary. Thanks. – Programmer Mar 28 '19 at 09:53
  • @JustABadProgrammer Without the code where you create the pipes, fork and execute the children we can only give general advice, not a specific recommendation how to solve your problem. If you want the loop `while(read(pipes[procid][0], buf, MAIN_BUF_LEN) > 0){` to terminate you have to make sure that all processes that created or inherited the pipe file descriptors close the writing end. – Bodo Mar 28 '19 at 12:15
  • Where do you open `outfileptr`? If the children inherit it from the parent you might get strange results. – Bodo Mar 28 '19 at 12:19
  • I suggest to use `dup2(pipes[procid][0], 0)` in the child and close all file descriptors greater than 2 before executing the client's processing function. – Bodo Mar 28 '19 at 12:22

0 Answers0