vfork()用于管道()

时间:2017-12-19 07:22:29

标签: c linux unix ipc

我从手册页中了解到, vfork()子进程使用与父进程相同的资源。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = vfork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

                /* Read in a string from the pipe */
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
        }

        return(0);
}

根据我的理解

close(fd[0]); // In child
write(fd[1], string, (strlen(string)+1));

在我们关闭管道读取结束fd [0]时,子进程中的上述代码行应该导致错误否13 SIGPIPE 。但这不会发生 输出是输入的 的 Received string: Hello, world! 任何人都可以解释一下原因吗?

1 个答案:

答案 0 :(得分:2)

vfork()函数是POSIX 2004的一部分,但不是POSIX 2008的一部分,POSIX 2008是当前版本(又名POSIX 2016)。使用vfork()可以做的事情非常非常有限。手册说:

  

vfork()函数应等同于fork(),但如果由vfork()创建的进程修改除{{1}类型的变量之外的任何数据,则行为未定义。用于存储来自pid_t的返回值,或者从调用vfork()的函数返回,或者在成功调用vfork()或其中一个_exit()之前调用任何其他函数功能族。

你不能从孩子那里打电话给exec;你不能致电close()

TL; DR - 不要使用write()

如果您对界面的复杂性表示勇敢和满意,可以从vfork()开始调查posix_spawn()函数及其20多个函数的支持人员。 OTOH,&#34; posix_spawn_然后在孩子身上做手术&#34;来自经典Unix的范例有很多优点;它比fork()函数更容易理解,并且最终也更灵活。并非所有平台都必须实现posix_spawn