Fork in a for loop

I have doubts about the following code snippet and its behavior:

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #define N 5 #define nt 1 int pm[N][2],pid[N]; int i,j,size; char s[100]; int count=0; int main() { for(i=1;i<N;i++) { printf("\ni=%d",i); if(pid[i]=fork() == -1) { printf("\n fork not wrking"); exit(1); } else if(pid[i]>0) { printf(" \n pid:%3d\n",pid[i]); break; } } return 0; } 

Initially, I thought the code would call the process and exit the loop. Thus,
1 spawns 2 and skips.
2 spawning 3 and omissions

3 caviar 4 and passes

4 spawns 5 and slips.

I tried to execute this code and was surprised by the answer I received (for printf I am in code). Here is the conclusion

  i=1 i=2 i=3 i=2 i=4 i=3 i=3 i=3 i=4 i=4 i=4 i=4 i=4 i=4 i=4 

Can someone please explain to me what is happening here. NOTE. I work on a Solaris machine.

+4
source share
5 answers

Update

You are missing a set of brackets in the updated code. It should be if ((pid[i] = fork()) == -1) not if (pid[i] = fork() == -1) !

The latter is equivalent to if (pid[i] = (fork() == -1)) due to priority rules. It finishes assigning 0 to pid[i] every time through the loop, so the parents think that they are child processes and do not exit the loop.


I agree with your analysis of what should happen. The parent must give birth to a child and then exit, so each printout i=n should be displayed only once.

Are you sure you typed it exactly as indicated in your question? I launched your program (with minor changes) and got the expected result:

 $ cat fork.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define N 5 int main() { int pid[N], i; for(i=1;i<N;i++) /* What's the total number of processes? */ { printf("i=%d\n",i); // Output of all the is if((pid[i]=fork())==-1) exit(1); else if(pid[i] > 0) break; } return 0; } $ gcc -o fork fork.c $ ./fork i=1 i=2 $ i=3 i=4 

Note that I have moved \n to the printout to the end. When you put it at the beginning of the line, you will get stdout , which will not be cleared, so you will get several printouts when the parent and child processes will clear the output buffers. This may be the cause of your problem. FWIW on my Mac, I received every printout twice.

+7
source

Fork creates a duplicate process containing everything the parent does, including file descriptors, etc. The only difference is the return value of fork (): the parent sees pid, the child sees zero.

The first iteration creates the first child. Its copy i also equal to 1, as well as the parent. The child goes out of the cycle. I get different results from you when I run it:

 [ wally@zf ~]$ ./a.out i=1 i=2 i=3 i=4 
+1
source

Expression

 if (pid[i] = fork() == -1) { 

will not do what you expect. You probably wanted to say

 if ((pid[i] = fork()) == -1) { 
+1
source

Each child process continues the cycle with the current value of i with growth. As a result, the first process prints i out of 1, and then spawns the child. Then both of these processes print i out of 2 and give birth to a child, for a total of four processes. All four of them print i out of 3 and each spawns a new process, and finally, all 8 processes print the value 4.

EDIT: Sorry, I missed the part in which the parent had to exit the loop. As for why this does not happen, this may be due to the fact that the PID is stored as a signed integer, but high enough to pass the maximum value with a sign, which makes it negative. Does it work if you make this replacement?

 else if(pid[i] > 0) break; 

to

 else if(pid[i] != 0) break; 
0
source

What flavor of Unix do you use. Is there any chance that the fork does not return int?

In this case, the comparison pid [i]> 0 may fail.

0
source

Source: https://habr.com/ru/post/1301174/


All Articles