vfork()用于管道()

问题描述 投票:-1回答:1

我从手册页中了解到,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));

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

c linux unix ipc
1个回答
2
投票

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

vfork()函数应该等效于fork(),除非行为是未定义的,如果由vfork()创建的过程要么修改除用于存储pid_t的返回值的vfork()类型的变量之外的任何数据,要么返回vfork()所用的函数。在成功调用_exit()或其中一个exec函数之前调用或调用任何其他函数。

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

TL; DR - 不要使用vfork()

如果你对界面的复杂性表示勇敢和满意,你可以调查posix_spawn()函数及其支持团队的20多个函数,从posix_spawn_开始。来自经典Unix的OTOH,“fork()然后做孩子的操作”范例有很多优点;它比posix_spawn功能更容易理解,并且最终也更灵活。并非所有平台都必须实现posix_spawn()

© www.soinside.com 2019 - 2024. All rights reserved.