linux进程创建 fork
进程创建
系统允许一个进程创建新进程,新进程即为子进程,子进程还可以创建新的子进程,形成进程树结构模型。
1 /* 2 man 2 fork 3 fork - create a child process 4 #include <sys/types.h> 5 #include <unistd.h> 6 pid_t fork(void); 7 返回值: 8 成功:fork()的返回值会返回两次,一次在父进程中,一次在子进程中 9 子进程中返回0,父进程中返回子进程 ID 10 失败:返回 -1(在父进程中返回,表示创建子进程失败 并设置 errno) 11 失败的两个主要原因: 12 1.当前系统的进程数已经达到了系统规定的上限,这时 errno 的值被设置为 EAGAIN 13 2.系统内存不足,这时 errno 的值被设置为 ENOMEM 14 */ 15 16 #include <sys/types.h> 17 #include <unistd.h> 18 #include <stdio.h> 19 20 int main() 21 { 22 //创建子进程 23 pid_t pid = fork();//分一个父进程 一个子进程 24 //判断是父进程还是子进程 25 if(pid > 0) 26 { 27 //如果大于0 返回的是 子进程的进程号 28 printf("parent process,pid:%d\tppid:%d\n",getpid(),getppid()); 29 } 30 else if(pid == 0) 31 { 32 //子进程 33 printf("child process,pid:%d\tppid:%d\n",getpid(),getppid()); 34 } 35 //for 循环 36 for(int i = 0; i < 5; i++) 37 { 38 printf("i: %d\t pid:%d\n",i,getpid()); 39 sleep(1);//1s 40 } 41 return 0; 42 }
父进程和子进程都执行了for循环代码
父子进程虚拟地址空间情况
父子进程的用户区完全复制拷贝,内核区同样拷贝,但是进程号不同 子进程栈空间pid返回0 父进程栈空间pid返回的是子进程的pid>0
#include <sys/types.h> #include <unistd.h> #include <stdio.h> int main() { int num = 10; pid_t pid = fork();//分一个父进程 一个子进程 //判断是父进程还是子进程 if(pid > 0) { //如果大于0 返回的是 子进程的进程号 printf("parent process,pid:%d\t ppid:%d\n",getpid(),getppid()); printf("parent num : %d\n",num); num += 10; printf("parent num+=10 : %d\n",num); } else if(pid == 0) { //子进程 printf("child process,pid:%d\t ppid:%d\n",getpid(),getppid()); printf("child num : %d\n",num); num += 100; printf("child num+=100 : %d\n",num); } //for 循环 for(int i = 0; i < 3; i++) { printf("i: %d\t pid:%d\n",i,getpid()); sleep(1);//1s } return 0; }
实际上,更准确来说,Linux的 fork() 使用是通过 写时拷贝 (copy - on - write) 实现。写时拷贝是一种可以推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间。只用在需要写入的时候才会复制地址空间,从而使各个进程拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读的方式共享。
注意:fork之后父子进程共享文件,fork产生的子进程与父进程相同的文件描述符指向相同的文件表,引用计数增加,共享文件偏移指针。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)