阅读背景:

fork之后,父进程和子进程是否共享由管道创建的文件描述符?

来源:互联网 
int main()
{
    int data_processed;
    int file_pipes[2];
    const char some_data[] = "123";
    char buffer[BUFSIZ + 1];
    pid_t fork_result;

    memset(buffer, '
int main()
{
    int data_processed;
    int file_pipes[2];
    const char some_data[] = "123";
    char buffer[BUFSIZ + 1];
    pid_t fork_result;

    memset(buffer, '\0', sizeof(buffer));

    if (pipe(file_pipes) == 0) {
        fork_result = fork();
        if (fork_result == -1) {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }

// We've made sure the fork worked, so if fork_result equals zero, we're in the child process.

        if (fork_result == 0) {
            data_processed = read(file_pipes[0], buffer, BUFSIZ);
            printf("Read %d bytes: %s\n", data_processed, buffer);
            exit(EXIT_SUCCESS);
        }

// Otherwise, we must be the parent process.

        else {
            data_processed = write(file_pipes[1], some_data,
                                   strlen(some_data));
            printf("Wrote %d bytes\n", data_processed);
        }
    }
    exit(EXIT_SUCCESS);
}

Based on my understanding, the child process created by fork doesn't share variables with its parent process. Then, why here the parent can write to one file descriptor and child process can get the data by reading from another file descriptor. Is this because they are controled somehow by the pipe function internally?

根据我的理解,fork创建的子进程不与其父进程共享变量。然后,为什么父进程可以写入一个文件描述符,子进程可以通过读取另一个文件描述符来获取数据。这是因为它们是由内部的管道功能以某种方式控制的吗?

3 个解决方案

#1


15  

File descriptors, including pipes, are duplicated on fork -- the child process ends up with the same file descriptor table, including stdin/out/err and the pipes, as the parent had immediately before the fork.

文件描述符(包括管道)在fork上重复 - 子进程以相同的文件描述符表结束,包括stdin / out / err和管道,因为父进程在fork之前。

Based on my understanding, the child process created by fork doesn't share variables with its parent process.

根据我的理解,fork创建的子进程不与其父进程共享变量。

This isn't entirely true -- changes to variables are not shared with the parent, but the values that the parent had immediately prior to the fork are all visible to the child afterwards.

这并不完全正确 - 对变量的更改不会与父级共享,但父级在fork之前的值在之后对子级都是可见的。

In any case, pipes exist within the operating system, not within the process. As such, data written to one end of the pipe becomes visible to any other process holding a FD for the other end. (If more than one process tries to read the data, the first process to try to read() data gets it, and any other processes miss out.)

在任何情况下,管道都存在于操作系统内,而不在进程内。这样,写入管道一端的数据对于另一端持有FD的任何其他进程都是可见的。 (如果多个进程尝试读取数据,则尝试读取()数据的第一个进程会获取该数据,并且任何其他进程都会丢失。)

#2


5  

The variables are not shared e.g. if you write file_pipes[0] = 999 in the child, it will not be reflected in the parent. The file descriptors are shared (FD number x in the child refers to the same thing as FD number x in the parent). This is why (for example) you can redirect the output of a shell script which executes other commands (because they share the same standard output file descriptor).

变量不是共享的,例如如果你在子文件中写入file_pipes [0] = 999,它将不会反映在父文件中。文件描述符是共享的(子编号中的FD编号x与父编号中的FD编号x相同)。这就是为什么(例如)您可以重定向执行其他命令的shell脚本的输出(因为它们共享相同的标准输出文件描述符)。

#3


1  

You're right - ordinary variables aren't shared between the parent and the child.

你是对的 - 父和孩子之间不共享普通变量。

However, pipes are not variables. They're a pseudo-file specifically designed to connect two independent processes together. When you write to a pipe, you're not changing a variable in the current process - you're sending data off to the operating system and asking it to make that data available to the next process to read from the pipe.

但是,管道不是变量。它们是专门用于将两个独立进程连接在一起的伪文件。当您写入管道时,您不会更改当前进程中的变量 - 您将数据发送到操作系统并要求它将该数据提供给下一个进程以从管道读取。

It's just like when you write to a real, on-disk file - except that the data isn't written to disk, it's just made available at the other end of the pipe.

就像你写入一个真实的磁盘文件一样 - 除了数据没有写入磁盘之外,它只是在管道的另一端可用。


', sizeof(buffer)); if (pipe(file_pipes) == 0) { fork_result = fork(); if (fork_result == -1) { fprintf(stderr, "Fork failure"); exit(EXIT_FAILURE); } // We've made sure the fork worked, so if fork_result equals zero, we're in the child process. if (fork_result == 0) { data_processed = read(file_pipes[0], buffer, BUFSIZ); printf("Read %d bytes: %s\n", data_processed, buffer); exit(EXIT_SUCCESS); } // Otherwise, we must be the parent process. else { data_processed = write(file_pipes[1], some_data, strlen(some_data)); printf("Wrote %d bytes\n", data_processed); } } exit(EXIT_SUCCESS); } int main() { int data_processed; int fi



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: