c - 当 parent 将数据写入与 fork 的 child 共享的管道并且两者都在读取数据时,如何防止 parent 在 child 之前读取数据?

标签 c linux pipe signals fork

我有一个 C 语言代码实现父子通信的管道。我经常需要从 parent 和 child 那里阅读和写作。一个较小版本的代码如下:

int main(){
    int cpid, var;
    int fds[2];

    pipe(fds);

    if((cpid=fork())==0){
        read(fds[0], &var, sizeof(int));
        printf("Recieved in child - %d\n",var);

        var = 3;
        write(fds[1], &var, sizeof(int));
        printf("Writing from child - %d\n",var);

        exit(0);
    }

    var = 5;
    write(fds[1], &var, sizeof(int));
    printf("Writing from parent - %d\n",var);

    // I need something here to execute following read only after child writes

    read(fds[0], &var, sizeof(int));
    printf("Recieved in parent - %d\n",var);

    waitpid(cpid,NULL,0);
    return 0;
}

但我面临的问题是,父进程中的读入是在从父进程写入后立即执行的。我需要防止这种情况发生。在 child 写完上面的代码之前,有什么办法可以让我们停止读取父对象吗?欢迎任何算法或建议。

PS:我已经尝试使用像 SUGUSR1 这样的信号并暂停父级直到子级发送信号但是由于信号没有排队,在这种情况下信号的概念对于多个子级父级管道通信失败。

最佳答案

根据@JonathanLeffler 和@EugeneSh 的评论。单管道不适合双向通信。所以上面的代码可以修改为使用一根管道用于父子通信,一根管道用于子父通信,如下所示:

int main(){
    int cpid, var;
    int p2c[2], c2p[2];

    pipe(p2c);
    pipe(c2p);

    if((cpid=fork())==0){
        read(p2c[0], &var, sizeof(int));
        printf("Recieved in child - %d\n",var);

        var = 3;
        write(c2p[1], &var, sizeof(int));
        printf("Writing from child - %d\n",var);

        exit(0);
    }

    var = 5;
    write(p2c[1], &var, sizeof(int));
    printf("Writing from parent - %d\n",var);

    read(c2p[0], &var, sizeof(int));
    printf("Recieved in parent - %d\n",var);

    waitpid(cpid,NULL,0);
    return 0;
}

这也适用于多子-父逻辑。

关于c - 当 parent 将数据写入与 fork 的 child 共享的管道并且两者都在读取数据时,如何防止 parent 在 child 之前读取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42282707/

相关文章:

c++ - 管道可以跨局域网计算机使用吗?

c - AWS IoT - JSON 格式不正确

c - MPI:如何让其他处理器等待主处理器直到其工作完成

linux - Linux 上的 CPU 限制后台进程

Windows:具有重定向输入和输出的子进程

c - 为什么我的 Fork 子进程不从管道读取?

c - armcc链接错误错误: L6769E in armcc while building a C project,是什么问题?

C 直方图错误数字

linux - CPU亲和性的优缺点

php - php 扩展崩溃 - 将内存地址转换为行号