我从手册页中了解到,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!
任何人都可以解释我的原因吗?
vfork()
函数是POSIX 2004的一部分,但不是POSIX 2008的一部分,POSIX 2008是当前版本(又名POSIX 2016)。你可以用vfork()
做的非常非常有限。手册说:
vfork()
函数应该等效于fork()
,除非行为是未定义的,如果由vfork()
创建的过程要么修改除用于存储pid_t
的返回值的vfork()
类型的变量之外的任何数据,要么返回vfork()
所用的函数。在成功调用_exit()
或其中一个exec
函数之前调用或调用任何其他函数。
你不能从孩子那里打电话给close()
;你不能打电话给write()
。
vfork()
。如果你对界面的复杂性表示勇敢和满意,你可以调查posix_spawn()
函数及其支持团队的20多个函数,从posix_spawn_
开始。来自经典Unix的OTOH,“fork()
然后做孩子的操作”范例有很多优点;它比posix_spawn
功能更容易理解,并且最终也更灵活。并非所有平台都必须实现posix_spawn()
。