Reputation: 2923
I'd like to know if there is a way to pause a process but continue the program.
I need to create processes like this:
But when I hit P4
it ends, dies and then P2 creates P5. Then P2 Dies and P1 creates P3 and the same thing happens there.
I need to create the whole 'tree' before the processes start to die.
Can't use wait
nor waitpid()
because it only targets it's son.
Is there a way to Pause P4 and continue from it's father ?
If I can't how could I achieve my goal ?
My currently code: It's creating in this order:
P1 -> P2 -> P4 -> P4 DIES -> P5 -> P5 DIES -> P2 DIES -> P3 -> P6 -> P6 DIES -> P7 -> P7 DIES -> P3 DIES -> P1 DIES
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
int main(){
clock_t t;
double time_taken;
t = clock();
int status;
pid_t idProcesso, pai;
printf("P1 created: %d\n", getpid());
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0: //P2
printf("P2 created: %d - son of P1: %d\n", getpid(), getppid());
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0: //P4
printf("P4 created: %d - son of P2: %d\n", getpid(), getppid());
sleep(1);
break;
default://P2
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0://P5
printf("P5 created: %d - son of P2: %d\n", getpid(), getppid());
break;
default://P2
sleep(1);
break;
}
break;
}
break;
default:
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0://P3
printf("P3 created: %d - son of P1: %d\n", getpid(), getppid());
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0://P6
printf("P6 created: %d - son of P3: %d\n", getpid(), getppid());
sleep(1);
break;
default://P3
idProcesso = fork();
switch(idProcesso)
{
case -1: exit(1);
case 0://P7
printf("P7 created: %d - son of P3: %d\n", getpid(), getppid());
break;
default://P3
break;
}
sleep(1);
break;
}
break;
default:
sleep(4);
break;
}
break;
}
printf("Process id: %d terminated\n", getpid());
exit(0);
}
Upvotes: 1
Views: 3623
Reputation: 25908
Processes run independently of each other, so you just need to:
Keep your child processes alive for long enough for all your processes to get created, which is easy enough to do using sleep()
, for instance; and
Don't start wait()
ing for any of your child processes until you've created them all.
Here's an example:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pids[8] = {0};
printf("P1 created (%lu).\n", (unsigned long) getpid());
for ( size_t i = 1; i < 3; ++i ) {
pids[i] = fork();
if ( pids[i] == -1 ) {
perror("fork() error");
exit(EXIT_FAILURE);
}
else if ( pids[i] == 0 ) {
printf("P%zu created (%lu).\n", i + 1, (unsigned long) getpid());
for ( size_t j = 1 + i * 2; j < 3 + i * 2; ++j ) {
pids[j] = fork();
if ( pids[j] == -1 ) {
perror("fork() error");
exit(EXIT_FAILURE);
}
else if ( pids[j] == 0 ) {
printf("P%zu created (%lu).\n", j + 1,
(unsigned long) getpid());
sleep(8 - j);
printf("P%zu exiting.\n", j + 1);
exit(EXIT_SUCCESS);
}
}
for ( size_t j = 2 + i * 2; j >= 1 + i * 2; --j ) {
if ( waitpid(pids[j], NULL, 0) == -1 ) {
perror("waitpid() error");
exit(EXIT_FAILURE);
}
printf("Waited for P%zu (%lu).\n", j + 1,
(unsigned long) pids[j]);
}
printf("P%zu exiting.\n", i + 1);
exit(EXIT_SUCCESS);
}
}
for ( size_t i = 2; i > 0; --i ) {
if ( waitpid(pids[i], NULL, 0) == -1 ) {
perror("waitpid() error");
exit(EXIT_FAILURE);
}
printf("Waited for P%zu (%lu).\n", i + 1, (unsigned long) pids[i]);
}
printf("P1 exiting.\n");
return 0;
}
with output:
paul@horus:~/src/sandbox$ ./procs
P1 created (27206).
P2 created (27207).
P3 created (27208).
P4 created (27209).
P5 created (27210).
P6 created (27211).
P7 created (27212).
P7 exiting.
Waited for P7 (27212).
P6 exiting.
Waited for P6 (27211).
P3 exiting.
Waited for P3 (27208).
P5 exiting.
Waited for P5 (27210).
P4 exiting.
Waited for P4 (27209).
P2 exiting.
Waited for P2 (27207).
P1 exiting.
paul@horus:~/src/sandbox$
Note that the order in which processes are run is inherently unpredictable, so each time you run it you could get slightly different results to the above. I have not attempted to make them create or exit in order, except for a half-hearted attempt at sleep()
in the four leaf processes, which is otherwise just there to keep them all alive for long enough. You can almost guarantee the execution and termination order with strategic calls to sleep()
, or guarantee it using some form of inter-process communication. As a general rule, you shouldn't care about this order, just about whether your actual work gets done in order.
But, it fulfills the criteria of keeping all the processes alive before any of them start to die.
Upvotes: 1