C叉和管的封闭端 [英] C Fork and Pipe closing ends

查看:113
本文介绍了C叉和管的封闭端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个需要与几个子进程进行双向通信的应用程序.我的父母就像一个查询引擎,不断从stdin读取单词并将其传递给每个子进程.子进程执行其处理,然后在其专用管道上写回父进程.

I am building an application that requires two way communication with a few child processes. My parent is like a query engine constantly reading words from stdin and passes it to each child process. The child processes perform their processing and writes back to the parent on their exclusive pipes.

从理论上讲,这是应该如何工作的,但是我仍然停留在实现细节上.第一个问题是我在分叉孩子之前创建2个管道吗?当我分叉时,我知道孩子将继承父对象的文件描述符集,这是否意味着将创建4个管道或仅复制2个管道.如果它们在子对象中被复制,那么这是否意味着如果我要在子对象中关闭文件描述符,它也会关闭父对象的文件描述符吗?

This is theoretically how it should work however I am stuck on the implementation details. The first issue is do I create 2 pipes before forking the child? When I fork, I know the child is going to inherit the parent's set of file descriptors, does this mean that 4 pipes will be created or simple 2 pipes just duplicated. If they are being duplicated in the child then does this mean if I were to close a file descriptor in the child, it would also close the parent's?

我的理论如下,我只需要澄清一下,并放在正确的道路上即可.这是未经测试的代码,我只是编写了它,目的是为了让您对我的想法有所了解.谢谢,感谢您的帮助.

My theory is the following and I simply need clarification and be put on the right track. This is untested code, I just wrote it to give you an idea of what I am thinking. Thanks, any help is appreciated.

int main(void){
    int fd[2][2]; //2 pipes for in/out

    //make the pipes
    pipe(fd[0]); //WRITING pipe
    pipe(fd[1]); //READING pipe

    if(fork() == 0){
        //child
        //close some ends
        close(fd[0][1]); //close the WRITING pipe write end
        close(fd[1][0]); //close the READING pipe read end

        //start the worker which will read from the WRITING pipe
        //and write back to the READING pipe
        start_worker(fd[0][0], fd[1][1]);
    }else{
        //parent
        //close the reading end of the WRITING pipe
        close(fd[0][0]);
        //close the writing end of the READING pipe
        close(fd[1][1]);
        //write data to the child down the WRITING pipe
        write(fd[0][1], "hello\n", 6);

        //read from the READING pipe 
        int nbytes;
        char word[MAX];
        while ((nbytes = read(fd[1][0], word, MAXWORD)) > 0){
            printf("Data from child is: %s\n", word);
        }
    }

}

推荐答案

在分叉时,不会复制管道本身.

The pipe itself is not duplicated upon fork.

单个管道是单向的,并且具有2个描述符-一个用于读取,一个用于写入.因此,在过程A中,您关闭了写入描述符,在进程B中关闭读取描述符->您具有从B到A的管道.

A single pipe is unidirectional, and has 2 descriptors - one for reading, one for writing. So in process A you close e.g. write descriptor, in process B you close read descriptor -> you have a pipe from B to A.

在一个进程中关闭描述符不会影响另一个进程中的描述符.分叉后,每个进程都有自己的描述符空间,这是父进程描述符的副本.以下摘录自 fork()手册页:

Closing a descriptor in one process doesn't affect the descriptor in another process. After forking each process has its own descriptor space, which is a copy of parent process descriptors. Here's an excerpt from fork() man page:

子进程应具有其父文件的自己的副本 描述符.孩子的每个文件描述符都应引用 与相同的文件描述符相同的打开文件描述 父母.

The child process shall have its own copy of the parent's file descriptors. Each of the child's file descriptors shall refer to the same open file description with the corresponding file descriptor of the parent.

这篇关于C叉和管的封闭端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆