当xxx
4个子进程处理时,我在第一个子进程执行后进入zzz
,而下一个进程甚至没有被执行。我不确定为什么会出现这种现象。我不是分叉的专家,每一个小费都受到赞赏。
fork()
这是我的代码:
wait()
整个过程尝试使用子进程计算Input data: ./forkexample 2 3 4 5
。在编译和运行之后,此序列运行:
#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);
}
在此之后,计算会等待某些事情,我无法弄清楚原因。
答案 0 :(得分:1)
您的子进程不会退出,而是继续运行用于父进程的代码。因此,在第一个子项将其结果写入管道后,它会开始分支另一个子进程,然后再次写入其自己的管道并输入wait()
。然后你有一个死锁 - 父进程等待第一个孩子退出,第一个孩子等待孩子退出。
您也不会检查任何write()
来电时的错误情况。如果你这样做,你会看到正在进行意外的write()
通话。
向子路径添加_exit()
调用应该会有所帮助,但此代码中还有许多其他问题。