Reputation:
While fork()
ing 4 children processes, I get into a wait()
after the first children process' execution and the next one doesn't even get executed. I am not sure why this phenomenon occurs. I am not an expert in forking and every tip is appreciated.
Input data: ./forkexample 2 3 4 5
And here is my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, const char **argv)
{
if (argc != 5)
{
printf("Argument # is invalid. %s < 4\n", argv[0]);
exit(1);
}
float a = atof(argv[1]);
float b = atof(argv[2]);
float c = atof(argv[3]);
float d = atof(argv[4]);
if ((a == 0.0) || (b == 0.0) || (c == 0.0) || (d == 0.0))
{
printf("Conversion error, invalid parameters!\n");
exit(1);
}
int ossz[2], kiv[2], szor[2], oszt[2];
int mainpid;
if ((pipe(ossz) < 0))
perror("pipe error(/)");
if ((pipe(kiv) < 0))
perror("pipe error(*)");
if ((pipe(szor) < 0))
perror("pipe error(-)");
if ((pipe(oszt) < 0))
perror("pipe error(*)");
mainpid = getpid();
pid_t osszeg, kivonas, szorzat, hanyados;
// (a+b*c) / (a-b+d-c) + a*b*c*d;
// *****************************+***********************************
if ((osszeg = fork()) == 0)
{
if (mainpid != getpid())
{ //osszeadast vegez el
float b1, c1, byteb1, bytec1;
byteb1 = read(ossz[0], &b1, sizeof(float));
printf("%d Osszeg read in %.2f\n", getpid(), b1);
bytec1 = read(ossz[0], &c1, sizeof(float));
printf("%d Osszeg read in %.2f\n", getpid(), c1);
close(ossz[0]);
c1 += b1;
write(ossz[1], &c1, sizeof(float));
printf("%d Osszeadas wrote %.2f\n", getpid(), c1);
}
else if (getpid() < 0)
{
printf("Error creating children process, cprog stops!\n");
exit(1);
}
}
// *****************************-***********************************
if ((kivonas = fork()) == 0)
{
if (mainpid != getpid())
{ //kivonast vegez el
float b2, c2, byteb2, bytec2;
byteb2 = read(kiv[0], &b2, sizeof(float));
printf("%d Kivonas read in %.2f\n", getpid(), b2);
bytec2 = read(kiv[0], &c2, sizeof(float));
printf("%d Kivonas read in %.2f\n", getpid(), c2);
close(kiv[0]);
c2 -= b2;
write(kiv[1], &c2, sizeof(float));
printf("%d Kivonas wrote %.2f\n", getpid(), c2);
}
else if (getpid() < 0)
{
printf("Error creating children process, cprog stops!\n");
exit(1);
}
}
// ***************************** Multiplication***********************************
if ((szorzat = fork()) == 0)
{
if (mainpid != getpid())
{ //szorzast vegez el
float b3, c3, byteb3, bytec3;
byteb3 = read(szor[0], &b3, sizeof(float));
printf("%d Szorzat read in %.2f\n", getpid(), b3);
bytec3 = read(szor[0], &c3, sizeof(float));
printf("%d Szorzat read in %.2f\n", getpid(), c3);
close(szor[0]);
c3 *= b3;
write(szor[1], &c3, sizeof(float));
printf("%d Szorzat wrote %.2f\n", getpid(), c3);
}
else if (getpid() < 0)
{
printf("Error creating children process, cprog stops!\n");
}
}
// *****************************Division***********************************
if ((hanyados = fork()) == 0)
{
if (mainpid != getpid())
{ //osztast vegez el
float b4, c4, byteb4, bytec4;
byteb4 = read(oszt[0], &b4, sizeof(float));
printf("%d Oszto read in %.2f\n", getpid(), b4);
bytec4 = read(oszt[0], &c4, sizeof(float));
printf("%d Oszto read in %.2f\n", getpid(), c4);
close(oszt[0]);
c4 = c4 / b4;
write(oszt[1], &c4, sizeof(float));
printf("%d Oszto wrote %.2f\n", getpid(), c4);
}
else if (getpid() < 0)
{
printf("Error creating children process, cprog stops!\n");
exit(1);
}
}
float szorzaser, osztaser, kivonaser, osszeger, vegeredmeny;
write(szor[1], &b, sizeof(float));
write(szor[1], &c, sizeof(float));
wait(NULL);
read(szor[0], &szorzaser, sizeof(float)); //b*c
printf("%d Parent got: %.2f /n", getpid(), szorzaser);
write(ossz[1], &a, sizeof(float));
write(ossz[1], &szorzaser, sizeof(float));
wait(NULL);
read(ossz[0], &osszeger, sizeof(float)); //a+szorzaser(b*c)
printf("%d Parent got: %.2f /n", getpid(), osszeger);
//***********************a+b*c**********************************************
write(ossz[1], &b, sizeof(float));
write(ossz[1], &d, sizeof(float));
wait(NULL);
read(ossz[0], &osszeger, sizeof(float)); //b+d
printf("%d Parent got: %.2f /n", getpid(), osszeger);
write(kiv[1], &a, sizeof(float));
write(kiv[1], &osszeger, sizeof(float));
wait(NULL);
read(kiv[0], &kivonaser, sizeof(float)); //a-osszeger(b+d)
printf("%d Paren t got: %.2f /n", getpid(), kivonaser);
write(kiv[1], &kivonaser, sizeof(float));
write(kiv[1], &c, sizeof(float));
wait(NULL);
read(kiv[0], &kivonaser, sizeof(float)); //kivonaser(a-b+d-c)
printf("%d Parent got: %.2f /n", getpid(), kivonaser);
write(oszt[1], &kivonaser, sizeof(float));
write(oszt[1], &osszeger, sizeof(float)); //betesszuk az osztas pipejaba
wait(NULL);
read(oszt[0], &osztaser, sizeof(float)); //(a+b*c) / (a-b+d-c)
printf("%d Parent got: %.2f /n", getpid(), osztaser);
//*************************(a-b+d-c)*********************************************
write(szor[1], &a, sizeof(float));
write(szor[1], &b, sizeof(float));
wait(NULL);
read(szor[0], &szorzaser, sizeof(float)); //a*b
printf("%d Parent got: %.2f /n", getpid(), szorzaser);
write(szor[1], &szorzaser, sizeof(float));
write(szor[1], &c, sizeof(float));
wait(NULL);
read(szor[0], &szorzaser, sizeof(float)); //a*b*c
printf("%d Parent got: %.2f /n", getpid(), szorzaser);
write(szor[1], &szorzaser, sizeof(float));
write(szor[1], &c, sizeof(float));
wait(NULL);
read(szor[0], &szorzaser, sizeof(float)); //a*b*c*d
printf("%d Parent got: %.2f /n", getpid(), szorzaser);
//************************* a*b*c*d *********************************************
write(ossz[1], &osztaser, sizeof(float));
write(ossz[1], &szorzaser, sizeof(float));
wait(NULL);
read(ossz[0], &vegeredmeny, sizeof(float)); //(a+b*c) / (a-b+d-c)+ a*b*c*d;
printf("%d Parent got: %.2f /n", getpid(), vegeredmeny);
close(ossz[0]);
close(ossz[1]);
close(kiv[0]);
close(kiv[1]);
close(szor[0]);
close(szor[1]);
close(oszt[0]);
close(oszt[1]);
printf("%d got the final result: %.2f!\n", getpid(), vegeredmeny);
return (0);
}
The whole process tries to calculate (a+b*c)/(a-b+d-c)+a*b*c*d
using the children processes. After compliation and running this sequence runs:
vargaelod23@vargaelod23-M5400:~/LinuxI/fork$ ./fork1 2 3 4 5
5459 Szorzat read in 3.00
5459 Szorzat read in 4.00
5459 Szorzat wrote 12.00
After this, the calculation waits for something and I can't figure out why.
Upvotes: 0
Views: 65
Reputation: 8604
Your child processes do not exit, but continue running the code intended for the parent process. So after the first child writes its result to the pipe, it starts forking another subprocesses and then writes again to its own pipe and enters wait()
. Then you have a deadlock – the parent process waits for the first child to exit and the first child waits for its child to exit.
You also don't check for error condition on any of the write()
calls. If you did, you would see that unexpected write()
call is being made.
Adding _exit()
calls to the child paths should help, but there are many other things wrong in this code.
Upvotes: 1