Unwanted child processes being created while file reading

  • A+

I am creating a multi process program. When I tried to call fork() in a for loop using if(f == 0) break;. I got the desired number of child processes.

However now, I am dealing with an input file, and the desired number of processes is not known initially. Here is the smallest possible example of my code.

FILE* file = fopen("sample_input.txt", "r"); while(fscanf(file, "%d", &order) == 1){           f = fork();     if(f == 0){         break;     }  } 

example sample_input.txt:

5 2 8 1 4 2 

Now thousands of child processes are being created (I want 6, the number of integers in the file), what could be the reason ? Is it something to do with the file pointer ?

Edit: I did some debugging with console outputs, the child processes are indeed breaking out of the loop. However the parent keeps reading a small file over and over. If I remove fork(), the loop executes 6 times as intended.

Edit2: I have a theory, I can't prove it maybe you can help me. It could be the situation that the file pointer is shared between processes, when a child exits, it closes the file and when the parent tries to read again, it just starts from the beginning (or some other weird behavior). Could it be the case ?

When the first process reads the first number, it actually reads the whole line into memory. The process forks.

The child process breaks the loop; what happens next is not specified, but it probably exits. The parent process now reads the second number and forks again. Again, the child exits and the parent reads the third number, forks, etc.

After the sixth number is read and the sixth child exits, the parent goes to read another buffer from the file. On Linux (or, more precisely, with the GNU C Library), you then get some weird effects. See the discussion in Why does forking my process cause the file to be read infinitely? to see the details. However, the children exiting adjust the read position of the file descriptor back to the start, so the parent can read more data again.

My answer to the other question shows that if the child processes close the file before exiting, this behaviour does not occur. (It shouldn't occur anyway, but it does, empirically.)

GLIBC Bug 23151

GLIBC Bug 23151 - A forked process with unclosed file does lseek before exit and can cause infinite loop in parent I/O.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: