PDA

View Full Version : forks and C - help !



cap10Ibraim
March 16th, 2011, 08:56 PM
#include <unistd.h>
#include <stdio.h>
int main(){
int x;
if( (x=fork())==-1 ) exit(1);
if( (x=fork())==-1 ) exit(2);
if( (x=fork())==-1 ) exit(3);
printf("\nI'm the process with id=%d and parent ID=%d\n",getpid(),getppid());
return 0;
}

why the execution didn't return and how to display the tree of the processes with
system("pstree") for one time

slavik
March 17th, 2011, 12:28 PM
you do realise that you fork 3 times and then just exit ... right?

Arndt
March 17th, 2011, 12:43 PM
#include <unistd.h>
#include <stdio.h>
int main(){
int x;
if( (x=fork())==-1 ) exit(1);
if( (x=fork())==-1 ) exit(2);
if( (x=fork())==-1 ) exit(3);
printf("\nI'm the process with id=%d and parent ID=%d\n",getpid(),getppid());
return 0;
}

why the execution didn't return and how to display the tree of the processes with
system("pstree") for one time

What do you mean by "didn't return"?

Portmanteaufu
March 17th, 2011, 01:28 PM
The parent process needs to call wait(...) or waitpid(...) for each of the forked child processes.

If the parent doesn't wait for the children to complete, it will exit before they get a chance to run. If the parent exits, any child processes die with it (unless you take special measures.)

Arndt
March 17th, 2011, 04:10 PM
The parent process needs to call wait(...) or waitpid(...) for each of the forked child processes.

If the parent doesn't wait for the children to complete, it will exit before they get a chance to run. If the parent exits, any child processes die with it (unless you take special measures.)

Did you run the program?

cap10Ibraim
March 17th, 2011, 04:10 PM
I need an example to show a tree of processes when calling n forks (2^n processes)
I've come up with this the program is called ex4


#include <unistd.h>
#include <stdio.h>
int main(){
int x;
if( (x=fork())==-1 ) exit(1);
if( (x=fork())==-1 ) exit(2);
if( (x=fork())==-1 ) exit(3);
system("sleep 30");
return 0;
}

then
pstree -p 1906
showed


bash(1906)───ex4(2024)─┬─ex4(2025)─┬─ex4(2027)─┬─e x4(2037)───sh(2045)───sleep(2+
│ │ └─sh(2039)───sleep(2043)
│ ├─ex4(2029)───sh(2035)───sleep(2040)
│ └─sh(2031)───sleep(2033)
├─ex4(2026)─┬─ex4(2036)───sh(2044)───sleep(20 46)
│ └─sh(2038)───sleep(2042)
├─ex4(2028)───sh(2034)───sleep(2041)
└─sh(2030)───sleep(2032)


is there a way to show the tree of ex4 only without the sleep ?

Arndt
March 17th, 2011, 04:13 PM
I need an example to show a tree of processes when calling n forks (2^n processes)
I've come up with this the program is called ex4


#include <unistd.h>
#include <stdio.h>
int main(){
int x;
if( (x=fork())==-1 ) exit(1);
if( (x=fork())==-1 ) exit(2);
if( (x=fork())==-1 ) exit(3);
system("sleep 30");
return 0;
}

then
pstree -p 1906
showed


bash(1906)───ex4(2024)─┬─ex4(2025)─┬─ex4(2027)─┬─e x4(2037)───sh(2045)───sleep(2+
│ │ └─sh(2039)───sleep(2043)
│ ├─ex4(2029)───sh(2035)───sleep(2040)
│ └─sh(2031)───sleep(2033)
├─ex4(2026)─┬─ex4(2036)───sh(2044)───sleep(20 46)
│ └─sh(2038)───sleep(2042)
├─ex4(2028)───sh(2034)───sleep(2041)
└─sh(2030)───sleep(2032)


is there a way to show the tree of ex4 only without the sleep ?

There's a library function 'sleep', too.

cap10Ibraim
March 17th, 2011, 04:16 PM
There's a library function 'sleep', too.
is there a way to call pstree from the program but for one time
- just one process should call it so it can show once ?

Arndt
March 17th, 2011, 04:47 PM
is there a way to call pstree from the program but for one time
- just one process should call it so it can show once ?

If you want to see the whole tree, all processes that were created, you need to ensure that one doesn't exit before another one is created, and the program is too simple now for that, without the sleep. With the sleep, you have the full picture.

What do you actually want to achieve?

cap10Ibraim
March 23rd, 2011, 08:52 PM
why printf("I'm the parent with pid=%d",pid); is not executed ?


#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
int x1,x2,x3,status;
if( (x1=fork())==0 ){
sleep(10);
exit(0);
}
if( (x2=fork())==0 ){
sleep(10);
exit(0);
}
if( (x3=fork())==0 ){
sleep(5);
exit(0);
}
int pid=getpid();
printf("I'm the parent with pid=%d",pid);
char *command="pstree -p ";
char command_long[20];
sprintf(command_long,"%s%d",command,pid);
system(command_long);
return 0;
}

Arndt
March 23rd, 2011, 09:30 PM
why printf("I'm the parent with pid=%d",pid); is not executed ?


#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
int x1,x2,x3,status;
if( (x1=fork())==0 ){
sleep(10);
exit(0);
}
if( (x2=fork())==0 ){
sleep(10);
exit(0);
}
if( (x3=fork())==0 ){
sleep(5);
exit(0);
}
int pid=getpid();
printf("I'm the parent with pid=%d",pid);
char *command="pstree -p ";
char command_long[20];
sprintf(command_long,"%s%d",command,pid);
system(command_long);
return 0;
}


You may need to output a newline too, in order for the output to reach the terminal. Try "I'm the parent with pid=%d\n".

trent.josephsen
March 23rd, 2011, 09:32 PM
Oops, too slow

Portmanteaufu
March 25th, 2011, 02:38 AM
Did you run the program?

No, I didn't. I was commenting on how fork() works in Linux. If the OP wants to guarantee that the child processes get an opportunity to run, (s)he needs to use wait().

Causing the parent program to sleep for some time after forking will increase the odds the child programs complete, but it's not a certainty.

Arndt
March 25th, 2011, 10:07 AM
No, I didn't. I was commenting on how fork() works in Linux. If the OP wants to guarantee that the child processes get an opportunity to run, (s)he needs to use wait().

Causing the parent program to sleep for some time after forking will increase the odds the child programs complete, but it's not a certainty.

The reason I asked was that if you had, you would have noticed that what you said about "If the parent exits, any child processes die with it" is not true. The parentless processes get 1 as their parent pid and continue running.

Portmanteaufu
March 28th, 2011, 01:50 AM
Huh! Welp, I learned something today.

I thought that what I was describing was the default behavior because shells send SIGHUP to their child processes when they die -- turns out you have to set that up with prctl().

Good work, Arndt.