fork,写时复制(copy-on-write),vfork
进程创建
进程创建分为三种情况
1.共享 父进程与子进程共享数据段、堆栈段、代码段,也就是说子进程对数据进行的改变会直接影响父进程。 2.写时复制(Copy-On-Write) 我简单地将这种技术理解为,当子进程执行写操作时,内核会将被修改的部分单独copy,单独操作。 3.直接拷贝 直接复制父进程的数据段、堆栈段,共享代码段。一、fork
fork()调用时,子进程会复制父进程数据段、堆栈段,并且使用新的物理地址以及虚拟地址存储。但父子进程共享代码段。但现在的实现采用了写时复制技术。
二、vfork
vfork()调用时,父子进程共享所有资源。但在调度上,使用vfork将保证子进程先于父进程被调度。
下面给出参考书的代码用以说明两者区别:
- fork
/********************************************************************** > File Name: t_fork.c > Author: 0nism > Email: fd98shadow@sina.com > Created Time: Sun 14 Oct 2018 02:41:39 PM CST ***********************************************************************/ #include#include #include static int idata = 111; // Allocated in data segment int main(int argc, char **argv) { int istack = 222; // Allocated in stack segment pid_t childPid; switch (childPid = fork()) { case -1: printf("err: fork\n"); return 0; case 0: idata *= 3; istack *= 3; break; default: sleep(3); break; } printf("PID=%ld %s idata=%d istack=%d\n", (long)getpid(), (childPid == 0) ? "child " : "parent ", idata, istack); exit(EXIT_SUCCESS); }
运行结果为
MISlike@10:56:~/process $ ./t_fork PID=5566 child idata=333 istack=666 PID=5565 parent idata=111 istack=222
无论是数据段还是堆栈段均完成了复制。
- vfork
/********************************************************************** > File Name: t_vfork.c > Author: 0nism > Email: fd98shadow@sina.com > Created Time: Sun 14 Oct 2018 11:21:22 PM CST ***********************************************************************/ #include#include #include int main(int argc, char **argv) { int istack = 222; switch (vfork()) { case -1: printf("err: vfork\n"); return 0; case 0: // 子进程优先执行,在父进程的虚拟地址空间中 sleep(3); // 即使休眠一段时间,父进程仍然不会先执行 write(STDOUT_FILENO, "Child excuting\n", 16); istack *= 3; // 这个变化将会被父进程知晓 _exit(EXIT_SUCCESS); default: // 父进程被锁住直到子进程消亡 write(STDOUT_FILENO, "Parent excuting\n", 16); printf("istack = %d\n", istack); _exit(EXIT_SUCCESS); } }
运行结果如下
Child excutingParent excutingistack = 666
可见子进程操作影响到了父进程,且此时父进程被阻塞,知道子进程消亡或者执行excu()。
posted on 2018-10-15 11:04 阅读( ...) 评论( ...)