I am required to create a process tree with relationships expressed as in the picture.
The problem is I must create all "nodes" in the order of the alphabet. I have gotten this far but my order is not consistent. I believe I am using waitpid
incorrectly?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char **argv)
{
pid_t pidA, pidB, pidC, pidD, pidE, pidF, pidG, pidI;
pidA = fork();
if (pidA < 0)
{
perror("A");
exit(1);
}
else if (pidA == 0)
{
printf("%d: A\n", getpid());
pidB = fork();
if (pidB < 0)
{
perror("B");
exit(1);
}
else if (pidB == 0)
{
printf("%d: B\n", getpid());
waitpid(pidD, NULL, 0);
pidE = fork();
if (pidE < 0)
{
perror("E");
exit(1);
}
else if (pidE == 0)
{
printf("%d: E\n", getpid());
waitpid(pidG, NULL, 0);
pidI = fork();
if (pidI < 0)
{
perror("E");
exit(1);
}
else if (pidI == 0)
{
printf("%d: I\n", getpid());
}
else
{
;
}
}
else
{
pidF = fork();
if (pidF < 0)
{
perror("F");
exit(1);
}
else if (pidF == 0)
{
printf("%d: F\n", getpid());
}
else
{
;
}
}
}
else
{
pidC = fork();
if (pidC < 0)
{
perror("B");
exit(1);
}
else if (pidC == 0)
{
printf("%d: C\n", getpid());
waitpid(pidF, NULL, 0); // !
pidG = fork();
if (pidG < 0)
{
perror("G");
exit(1);
}
else if (pidG == 0)
{
printf("%d: G\n", getpid());
}
else
{
;
}
}
else
{
pidD = fork();
if (pidD < 0)
{
perror("B");
exit(1);
}
else if (pidD == 0)
{
printf("%d: D\n", getpid());
}
else
{
;
}
}
}
}
else
{
;
}
return 0;
}
Output is not consistent so I think this part wouldn't help much.
5644: A
5645: B
5646: C
5647: D
5648: G
5650: F
5649: E
5651: I
The principal problem here is that waitpid
only suffices for synchronization when all of the processes are linearly related (i.e., parent process, child process, "grandchild" process, etc.).
However, your processes, as exhibited by the diagram, are not linearly related. You can see this issue arise when you call waitpid(pidD, NULL, 0);
from within the B process. Not only is pidD
not defined in this context but the D process is not a child of the B process and so waitpid
is inappropriate.
@EOF makes a good point that trying to run multiple processes in series defeats the purpose of having multiple processes. However, if you just want to do this exercise as a fun brain teaser, I'd recommend setting up pipe
s in the original process and then closing the write end when the appropriate process wants to signal that it has exited. The process that is waiting for the first process to end can call select
on the read end.