vfork 与fork异同总结
前言
调⽤fork或vfork函数是Linux创建⼀个新进程的⽅法.
fork
由fork创建的新进程被称为⼦进程(child process)。该函数被调⽤⼀次,但返回两次。两次返回的区别是⼦进程的返回值是0,⽽⽗进程的返回 值则是新⼦进程的进程ID。
fork之后经常跟随着exec。作为替代,使⽤了在写时复制(Copy-On-Write,COW)的技术。这些区域由⽗、⼦进程共享,⽽且内核将它们的存取许可权改变为只读的。如果有进程试图修改这些区域,则内核为有关部分,典型的是虚存系统中的“⻚”,做⼀个拷⻉。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int globvar = 6; /* external variable in initialized data */
char buf[] = "a write to stdout\n";
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) //write函数是不带缓存的。
exit(-1);
//因为在fork之前调⽤write,所以其数据写到标准输出⼀次。但是,标准I/O库是带缓存的。
//如果标准输出连到终端设备,则它是⾏缓存的,否则它是全缓存的。
printf("before fork\n"); /* we don't flush stdout */
if ((pid = fork()) < 0) {
exit(-1);
} else if (pid == 0) { /* child */
globvar++; /* modify variables */
var++;
} else {
sleep(2); /* parent */
}
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
exit(0);
}
vfork
vfork与fork⼀样都创建⼀个⼦进程, 但是它并不将⽗进程的地址空间完全复制到⼦进程中,因为⼦进程会⽴即调⽤exec(或exit), 也就不会存访该地址空间。
vfork和fork之间的另⼀个区别是:vfork保证⼦进程先运⾏,在它调⽤exec或exit之后⽗进程才可能被调度运⾏。(如果在调⽤这两个函数之前⼦进程依赖于⽗进程的进⼀步动作,则会导致死锁。)
调用vfork后,如果子进程修改数据、函数调用、或者没有调用exec或exit之后就返回可能会出现未知的错误。
测试例子
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int count = 1;
int child;
printf("Before create son, the father's count is:%d\n", count);
if((child = vfork())< 0)
{
perror("fork error : ");
}
else if(child == 0)
{
printf("This is son, his count is: %d (%p). and his pid is: %d\n", ++count, &count, getpid());
exit(0); //如果不是exit或exec返回,将会发生未知错误
}
else
{
printf(" This is father, his count is: %d (%p), his pid is: %d\n", ++count, &count, getpid());
sleep(1);
}
return EXIT_SUCCESS;
}
总结
fork函数生成的子进程会写时复制的技术对父进程的数据进行复制。父子进程调度根据操作系统的调度来确定。
vfork函数生成的子进程与父进程共享数据。并优先执行。通过 vfork() 创建的子进程会执行完后,才到父进程执行。
进程页表的定义
The page table is where the operating system stores its mappings of virtual addresses to physical addresses, with each mapping also known as a page table entry。参考https://en.wikipedia.org/wiki/Page_table。
参考资料
[1].https://stackoverflow.com/questions/20030776/how-can-i-see-a-page-table-maintained-by-each-process-in-virtual-memory-linux
[2].http://man7.org/linux/man-pages/man2/vfork.2.html
[3].http://man7.org/linux/man-pages/man2/fork.2.html
[4].https://www.amazon.com/Advanced-Programming-UNIX-Environment-3rd/dp/0321637739
————————————————
版权声明:本文为优快云博主「zhang_dawei666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/xiangguiwang/article/details/81475345