gpt4 book ai didi

c - 在 linux 中读写 PIPE

转载 作者:IT王子 更新时间:2023-10-29 01:09:26 24 4
gpt4 key购买 nike

一个简单的linux多进程程序。输入一些数字,例如 ./findPrime 10 20 30。该程序将创建 3 个子进程来找出 2-10、10-20、20-30 之间的所有素数。一旦子进程找到质数,它将通过管道写入“2 is prime”并发送给父进程。家长会将其打印在屏幕上。这里的问题是,我使用 while 循环将消息写入管道并在父端使用另一个 while 循环来接收消息,但是使用下面的代码,它只显示第一条消息,所以我想知道什么`继续,我怎样才能继续从那个管道读取?我错过了什么吗?非常感谢!

char readBuffer[100];
char outBuffer[15];
int pids[argc];
int fd[2];
pipe(fd);

for(i = 0; i < argc; i++)
{
if( i == 0)
bottom = 2;
else
bottom = args[i - 1];
top = args[i];

pids[i] = fork();

if(pids[i] == 0)
{
printf("Child %d: bottom=%d, top=%d\n", getpid(), bottom, top);

close(fd[0]);

j = bottom;
while(j <= top)
{
int res = findPrime(j);

if(res == 1)
{
sprintf(outBuffer, "%d is prime", j);
write(fd[1], outBuffer, (strlen(outBuffer)+1));
}

j++;
}

exit(0x47);
}
else if(pids[i] < 0)
{
fprintf(stderr, "fork failed! errno = %i\n", errno);
break;
}
else
{
close(fd[1]);
while((nbytes = read(fd[0], readBuffer, sizeof(readBuffer))) > 0 )
printf("%s\n", readBuffer);

int status = 0;
pid = waitpid(pids[i], &status, 0);

if(pid >= 0)
printf("Child %d exited cleanly\n", pid);
}
}

并且这些子进程应该按照它们创建的顺序运行,比如进程 1 完成后,进程 2 将运行,进程 3 将在进程 2 之后运行。我还希望父进程在收到消息时立即显示消息。

最佳答案

父/子在 fork 时共享他们的文件描述符(就像他们现在一样)。您的直接问题是您关闭了父级中的 fd[1]。当第一个 child 结束时,进程结束意味着 fd[1] 将在 child 中自动关闭。由于操作系统不再具有对文件描述符的任何有效引用,因此它变得无效。所以你的管道写入在所有后续的 child 中都失败了。

所以不要关闭父级中的 fd[1]。

但是你还有其他问题。一个跳出来的是,如果您的子进程之一没有找到素数,它将永远不会写入管道。然而, parent 将永远阻塞等待阅读永远不会到达的东西。通过不关闭父级中的 fd[1],您将看不到 EOF - 即父级中的 read() == 0。因此,一种解决方案是通过管道传回“完成”消息,并让父级解析该内容。

更好的解决方案是考虑重新设计。通过在程序开始时解析命令行参数来计算您将需要的进程数。然后为您将需要的管道描述符的数量动态分配空间,并为每个进程提供自己的一对。这可以完全避免一切,是一种更标准的做事方式。

关于c - 在 linux 中读写 PIPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18950398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com