【问题标题】:vfork() usage with pipe()vfork() 与 pipe() 一起使用
【发布时间】:2018-06-01 14:03:53
【问题描述】:

我从手册页了解到的是 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] 时,子进程中的上述代码行应该会导致 error no 13 SIGPIPE。但这并没有发生 输入输出是 Received string: Hello, world! 谁能解释一下原因?

【问题讨论】:

标签: c linux unix ipc


【解决方案1】:

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

vfork() 函数应等效于 fork(),除了如果vfork() 创建的进程修改了除用于存储返回值的pid_t 类型变量以外的任何数据,则行为未定义vfork(),或从调用vfork() 的函数返回,或在成功调用_exit()exec 系列函数之一之前调用任何其他函数。

您不能从孩子那里拨打close();你不能打电话给write()

TL;DR — 不要使用vfork()

如果您对界面的复杂性感到勇敢和满意,您可以研究 posix_spawn() 函数及其从 posix_spawn_ 开始的 20 多个函数的支持团队。 OTOH,经典 Unix 中的“fork() 然后在子节点中执行操作”范式有很多优点;它比posix_spawn 函数更容易理解,最终也更灵活。也不是所有平台都必须实现posix_spawn()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多