C - 子进程连续从管道读取两次,而不是读取一次然后阻塞

标签 c fork pipe

我需要构建两个程序:一个用 C 语言编写的服务器和一个客户端,它们实现以下功能:

  1. 当我启动服务器时,他会创建一个命名管道 (O_RDONLY),它会阻塞自身,直到客户端连接为止。
  2. 客户端使用 O_WRONLY 打开的命名管道向客户端发送一条消息,解锁服务器。
  3. 服务器接收消息,然后将该消息传递给子级(使用匿名管道),子级在屏幕上打印该消息。

    1. 如果未创建子进程,则父进程会创建一个
    2. child 应该从每个客户端的匿名管道1消息中读取。这意味着 child 应该从无到有阅读。通过管道,打印消息,然后阻塞直到下一个客户端。

我现在遇到的问题是,有时当只有 1 个连接的客户端时, child 会阅读并打印消息两次

我已经在这上面呆了 8 个小时了,但我还是不明白。请有人帮我解决这个问题,我在这里快疯了。这是我到目前为止的代码:

客户端

int main(int argc, char* argv[]){
int pPedido;
pPedido = open("pedido",O_WRONLY);
char buffer[6] = "ABCDE";
write(pPedido,buffer,6);
printf("FECHOU\n");
return 0;
}

服务器

int main(int argc, char* argv[]){
int exists = 0;
int pipeID[2];
int pPedido;
char buffer [100];
mkfifo("pedido",0666);

while(1){
    pPedido = open("pedido",O_RDONLY);
    read(pPedido,buffer,6);

    if(exists == 1){
        write(pipeID[1],"ABC",4);
    }
    else{
        pipe(pipeID);
        if(fork() == 0){
            char bufferzito[100];
            while(1){
                read(pipeID[0],bufferzito,4);
                printf("%s\n",bufferzito);
            }
        }
        else{
            write(pipeID[1],"ABC",4);
            exists = 1;
        }
    }
}
return 0;
}

这些是我使用的包含内容。我认为其中一些是不必要的。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

最佳答案

您没有检查来自 openread 的返回值。这两个函数都可以返回 -1 来指示错误。

可能发生的情况是,在服务器 while 循环的第二次迭代中,打开或读取立即返回,返回值为 -1(错误),因此循环会再次执行。

调用read或open后,检查返回值,如果返回-1,还检查errno。

您还会在循环的每次迭代中一次又一次地打开相同的 fifo,而不会关闭它。

关于C - 子进程连续从管道读取两次,而不是读取一次然后阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23964525/

相关文章:

c - 初始化元素不是常量

c++ - 与 fork() 共享堆内存

c - 局部变量地址用作 errno

c - 在 C 中使用 HTTP POST 上传 JPEG

c - 使用两个管道的双向进程间通信

C - 管道和 fork - 奇怪的内存垃圾

c - 使用管道将整数从 n 个子级发送到父级 (c/unix)

scala - 如何将 Scalding TypedPipe 转换为 Iterator

c - 如何使用一个程序的返回值作为另一个程序的输入?

c - SIMD 代码与标量代码