fork进程复制
1.父子进程
如果B进程是由A进程fork复制出来的,那么我们就说A时B的父进程,B是A的子进程。
2. fork函数
pid_t fork(void);
返回值:失败返回-1;而成功调用后有两个返回值,子进程返回0,父进程返回子进程的pid。
拓展:
getpid 可以得到当前进程的pid
getppid 可以得到当前进程父进程的pid
子进程创建成功后:
代码执行的位置:父进程执行到哪,子进程就从哪开始执行。
执行顺序:不一定,谁抢到CPU谁就执行。
简单的讲,就是fork之后,创造出了一个几乎与之相同的进程。
子进程是父进程的副本,它将共享父进程的数据空间、栈、堆的资源。
3.写时拷贝机制
只有进程空间各段的内容发生变化时,才会将父进程的内容复制一份给子进程。
在fork之后exec之前,父进程与子进程使用的是相同的物理空间(内存区),子进程的数据段、代码段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,其对应的物理空间是同一个。
只有当父子进程中有更改相应的段行为时(即写时)再为子进程分配物理地址,如果不是exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段仍共享父进程的物理空间(因为两者代码完全相同);而如果是exec,由于两者代码段也不同了,子进程代码段就会单独分配物理空间。
示例1:
我们发现它打印了3个A,这是因为
示例2:
我们发现它竟然打印了8个A…究其原因,不过是因为没有\n罢了。
printf只是将A放到了缓冲区,而缓冲区只有经过一些操作才会刷新到屏幕上:
1.遇到\n EOF 或是fflush刷新
2.或者缓冲区满 或是文件描述符关闭
3.或是程序退出
而当我们写上\n之后,情况就变了