pid_t fork(void) 父进程创建一个子进程,父进程和子进程的PCB完全相同,除了pid,具有相同的用户态代码和数据,占用不同的内存地址。
1 #include<sys/types.h> 2 #include<unistd.h> 3 #include<stdio.h> 4 #include<stdlib.h> 5 int main() { 6 const char *message; 7 printf("before fork\n"); 8 pid_t pid; 9 pid = fork(); 10 if(pid < 0) { 11 exit(-1); 12 } 13 else if(pid == 0) { 14 message = "child"; 15 } 16 else { 17 message = "parent"; 18 } 19 int i = 0; 20 while(i < 5) { 21 printf("%d --> %s\n",i,message); 22 sleep(1); 23 ++i; 24 } 25 return 0; 26 }
before fork
0 --> parent
0 --> child
1 --> parent
1 --> child
2 --> parent
2 --> child
3 --> parent
3 --> child
4 --> parent
4 --> child
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
父进程执行到9行,fork进入内核,创建一个子进程,子进程和父进程具有完全相同PCB(除了pid),用户态代码和数据以及进程的状态,但是占用不同的内存地址。
子进程把父进程的代码从开头-->fork-->到结束全部copy过来。
此时,父进程在内核等待返回,子进程因为具有相同的PCB和进程状态,所以子进程也处于等待返回状态(6-9行不再执行,但是具有父进程拥有的变量和资源)。等到CPU下次调用到父进程或子进程时,父进程返回子进程的pid>0,
如果创建子进程失败,父进程返回的pid<0;子进程返回的pid=0;
因为父子具有完全相同的代码,所以父子进程根据pid选择性执行if else的某个分钟。 超出if else 代码块的语句是父子进程都要执行的。