进程
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { puts("Begin"); int pid = fork(); if(pid==0) { puts("Child"); }else { puts("Parent"); } puts("End"); }
在执行fork的时候产生一个子进程,根据pid区分是子进程,还是父进程,pid为0,表示子进程。
输出结果为:
Begin
Parent
End
Child
End
注意点:
1、fork的时候拷贝父进程相同的代码,所以在输出的结果中可以看到两个End。
2、是子进程先输出,还是父进程先输出,依赖于具体的Linux内核。例子中的内核为
root@typhoeus79 ice_test_m guosong]# uname -a Linux typhoeus79 2.6.30-SINA BASE_1 SMP Wed Sep 2 20:30:47 CST 2009 x86_64 x86_64 x86_64 GNU/Linux
写时拷贝(COW)
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。
vfork
内核连子进程的虚拟地址空间结构也不创建了,直接共享了父进程的虚拟空间。
页只读模式
Linux的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。
资源的复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候。在页根本不会被写入的情况下—举例来说,fork()后立即调用exec()—它们就无需复制了。fork()的实际开销就是复制父进程的页表以及给子进程创建惟一的进程描述符。
线程
线程由来,共享内存
通过pthead_create
detach以及join
SMP对称多处理器