【进程控制】-1-进程创建
** 博主名称**迷途之人不知返 个人专栏: 《C语言》、《数据结构》、《C》、《Linux》️ Gitee仓库: 《C语言》、《数据结构》、《C》、《Linux》/ 算法专栏: 《算法精选集》进程创建1、概述2、回顾fork创建子进程2、再谈写时拷贝2.1、触发机制2.2、“拷贝”原因3、fork常见用法4、fork调用失败的原因5、一个实际应用场景——fork的妙用1、概述进程的创建本质上是操作系统中多了一个进程。进程包含两大部分内核数据结构侧重管理。如task_struct mm_struct vm_area_struct...代码与数据侧重执行。同时进程具有独立性。意味着进程之间代码数据和内核结构是相互独立的。2、回顾fork创建子进程fork作为系统调用功能是创建子进程。fork之后的代码和数据连同全局变量为父进程与子进程共用。我们回顾fork的三点细节fork给子进程返回0而给父进程返回创建成功的子进程的pid父进程需要得到子进程pid以管理子进程而子进程只需要知道创建成功即可。一个函数返回两次fork父与子共用代码父进程有一个return语句子进程也有一个return语句。(同一个变量)地址相同内容不同写时拷贝。2、再谈写时拷贝这里我们关注写时拷贝的两点写时拷贝触发的机制为什么要“拷贝”。2.1、触发机制我们知道子进程刚创建出来父子进程是共用数据的当子进程需要对数据进行修改那么写时拷贝就会发生。具体是什么样子的呢还记得吗虚拟地址空间里头的页表不仅存有虚拟地址、物理地址还有一项权限位。当只有父进程的时候页表上数据(地址)会标上rw可读写权限而创建子进程后父与子共用数据时父进程和子进程页表上的数据就会标记成r只读权限。当子进程(或者父进程)想要修改数据时由于数据在页表的权限是只读转化失败触发报错操作系统就会检查进而发现原来子(父)进程想要修改数据于是进行写时拷贝然后修改各自页表的权限位。所以进程fork之后通过修改页表权限位的方式来触发报错进而引发操作系统的介入最终完成写时拷贝。2.2、“拷贝”原因对于写时拷贝有人可能还有疑问为什么还要拷贝呢我直接新开辟一个空间不就好了实际上写入的方式除了覆盖写入还有在原来基础上进行修改的写入。为了同时满足这两个条件Linux就实现成拷贝而不是仅仅开辟一个新空间。// 覆盖写入intcount10;count20;// 修改写入intcount10;count;3、fork常见用法fork有两个常见用法父进程希望复制自己使父子进程执行不同的代码段。比如父进程执行等待客户请求的函数子进程执行处理请求的函数。父进程希望创建一个子进程执行一个之前从未出现的程序。这就要用到以后的进程程序替换的知识。4、fork调用失败的原因原因有二内存资源不够进程数量超过限定值。5、一个实际应用场景——fork的妙用我们来实现一个程序父进程修改修改数据子进程备份数据。由于我们还没有学习文件而且向屏幕写入本质也是向一个文件写入所以子进程就把数据打印出来就可以了。#includestdio.h#includestdlib.h#includetime.h#includeunistd.h#includesys/types.h#defineNUM10intarr[NUM];voidChange(){inti0;for(;iNUM;i)arr[i]irand();printf(Origin: \n);for(i0;iNUM;i)printf(%d ,arr[i]);printf(\n);}voidBackup(){pid_tidfork();if(id0){perror(fork failed!\n);exit(2);}elseif(id0){// 子进程printf(backup: \n);inti0;for(;iNUM;i)printf(%d ,arr[i]);printf(\n);sleep(10);// 不要让子进程那么快退出exit(1);}}intmain(){srand((unsignedint)time(NULL));while(1){Change();Backup();sleep(5);}return0;}我们就完成了一边修改数据一边数据备份的工作至此我们就演示了如何利用fork 写时拷贝进行安全备份。这就匹配上了我们将数据保存到磁盘的需求。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →