gpt4 book ai didi

c - 在 C 中使用管道进行父子 IPC 会使程序阻塞

转载 作者:太空宇宙 更新时间:2023-11-04 03:08:41 24 4
gpt4 key购买 nike

我正在编写一个服务器,它在接受套接字连接时 fork() 关闭子进程。

当子进程与客户端通信时,它必须将部分信息发送回父进程。我正在使用管道来完成此操作。

问题是,当我尝试进行父子 IPC 时,父对象在读取子对象的输入时会阻塞。这意味着,即使子进程并发运行,它们也只能一次处理一个,因为它们都在等待父进程。

我的代码看起来像这样(为简洁起见删除了错误检查):

/* loop: wait for clients to connect */
for(;;) {

pipe(write_to_parent); /* create pipe between parent and child */
pipe(write_to_child); /* create pipe between parent and child */

newsockfd = accept(...);

pid = fork();

if (pid == 0) { /* child process */
close(write_to_parent[0]);
close(write_to_child[1]);

printf("Connected!\n");

while ((rc = recv(newsockfd, ...)) > 0) {
/* process socket request */

/* write stuff to parent that is related to what we recv'd from client */
rc = write(write_to_parent[1], &buf, 1024);
}

printf("Disconnected!\n");

exit(0);
} else { /* parent */

close(write_to_parent[1]);
close(write_to_child[0]);

while (read(write_to_parent[0], &buf, 1024) > 0) {
/* accept data from child process, and do some processing */
}
}
}

所以我的问题是,我该如何解决这个问题?我怎样才能让 parent 以不阻塞的方式使用管道与 child 沟通?

这甚至可以用管道实现,还是我应该使用共享内存(我猜是用信号量)或消息队列来代替? (我读过这篇文章:Comparing Unix/Linux IPC,但很难找到这些任务是如何实际完成的例子。)

更多详情:

我有一个执行以下操作的测试程序:1.连接服务器2. sleep (5)3.断开与服务器的连接

当我运行该程序的 2 个实例时,服务器输出如下:

connected!
// pause for 5 seconds
disconnected!
connected!
// pause for 5 seconds
disconnected!

显然一次处理每个客户。

当我删除 IPC - 当我从父项和子项中删除管道 read() 和 write() 时,我得到了这个:

connected!
connected!
// pause for 5ish seconds
disconnected!
disconnected!

这就是我想要的!

关于如何实现此目标的任何想法? (或者我应该改变解决这个问题的方式?)

(编辑:这是网络类(class)作业的一部分。我们正在实现一个 P2P 协议(protocol),该协议(protocol)使用集中式服务器来管理对等点。我们可以使用任何语言,我想我会试一试C.)

最佳答案

我在下面写下了答案,在重新阅读您的问题后,我发现我完全错过了您的实际问题。但是,它在任何情况下都可能是有用的信息。

要回答您并发的父问题,您需要让父设置一个 select() 循环来随时处理来自其任何子项的可能响应。您将需要:

  • 跟踪有多少 child 开放
  • 每个 child 准备一套 pipe
  • 使用带有 select() 的循环来接受传入的连接(因为它们可能随时发生)以及来自任何 child 的传入数据
  • 使用waitpid()收割终止的 child

这项技术很强大,但确实需要大量簿记才能正确设置。


在父进程中打开的文件句柄默认在子进程中继承。问题可能是父级和子级管道的写端仍然打开,所以当父级从管道读取时,它永远看不到它的末端。在开始从 write_to_parent[0] 读取之前,立即尝试在父级中使用 close(write_to_parent[1])。所以:

} else { /* parent */
close(write_to_parent[1]);
while (read(write_to_parent[0], &buf, 1024) > 0) {
/* accept data from child process, and do some processing */
}
}

关于c - 在 C 中使用管道进行父子 IPC 会使程序阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/575602/

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