- 1、本文档共15页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
新的进程通过克隆旧的进程来建立,当前进程是通过fork()系统调用来建立新的进程 当系统调用结束时,内核在系统的物理内存中为新进程分配新的task_struct结构,并为新进程要使用的堆栈分配物理页和进程标志符 父进程和子进程共享打开的文件 fork()的简单流程 如上图所示,分别使fork调用前后的两个部分 PC指向当前执行的语句,fork之前,它指向第一个printf语句,fork调用之后进程A、B一起运行,A是父进程,B是子进程-进程A的副本,执行与A一样的程序。两个pc都指向第二个printf语句。也就是AB从程序的相同点开始执行 Fork()执行的内存变动如下: 分配1页给task_struct结构 分配1页给内核堆栈 分配1页给pg_dir并且给page_tables分配一些页 硬件相关的变化 SS被置为内核堆栈(0x10) ESP被置为新分配栈的顶端(kernel_stack_page) CR3指向新分配的页目录 (由copy_page_table()完成) Idt=_LDT(task_nr)建立新的局部描述符 为新的任务状态段(tss)和局部描述符表(ldt[])装入gdt 从父进程继承剩下的寄存器 Pid_t fork(void); 由fork创建的新进程称为子进程。该函数被调用一次,会返回两次。给子进程的返回值是0,给父进程的返回值是子进程的进程ID。然后子进程和父进程继续执行fork之后的指令。子进程拥有父进程数据空间,堆和栈的拷贝,但是它们并不是共享这些存储空间。这里就用到了 “写时复制”技术 写时复制技术(copy_on_write) Linux通过写时复制技术来调入执行的程序 Linux将可写虚拟内存页的页表项标志为只读,当进程向该内存页写入数据时,处理器会发现内存访问中的问题(向只读页中写入),然后会导致操作系统可以捕获的页故障,由操作系统来完成内存页的复制 一个给定的物理页面可以代表多个逻辑页面,当这个页被一个进程从另一个进程处得到共享时,它是逻辑上的拷贝 如前面的fork调用,逻辑拷贝整个进程的地址空间,仅当试图修改页面(产生写错误)才真正的拷贝 用fork创建子进程之后,为了让父进程和子进程执行不同的任务,经常需要调用一种exec函数以执行另一个程序。当进程调用exec函数时,该进程完全由新程序替代。新程序从main开始执行 exec并不创建新进程,前后进程ID是不变的。它是用另外一个程序替代了当前进程的正文,数据,堆和栈 exec执行时的内存变化 1页分配给可执行文件头 1页或者多页分配给堆栈 硬件相关的变化: clear_page_tables()移去旧页 在新的LDT[]中设置描述符 包含argv和envp的“脏”页被分配 设置调用者的指针 设置调用者的堆栈指针指向建立的堆栈 更新内存段的边界 因为fork只能建立相同程序的副本,如果它是程序员唯一可以使用的建立进程的手段,会影响linux的性能 exec系列系统调用把新进程装入调用进程的地址空间,改变调用进程的代码。如果exec成功,调用者进程将被覆盖,从新进程的入口地址开始执行。exec只用新进程取代了原来的进程。并且没有返回数据 删除内核对终止进程的大部分引用: 信号量队列中的进程描述符 删除进程描述符中与分页、文件系统、打开文件描述符和信号处理相关数据结构 减小进程所用模块的引用计数 将进程描述符的exit_code字段设置为终止代号 更新父子进程的亲属关系,强制将自己的子进程作为其它某个进程的子进程,以等待该父进程进行删除 调用schedule()进行调度 一般当一个进程终止后都会发送SIGCHLD信号给它的父进程,并由此变为僵死进程直到父进程接收了其状态报告其资源才会被系统释放; ??? 处理方法有3种: ??? 1. 当子进程终止时父进程接收SIGCHLD信号并调用waitpid()函数接收其状态报告,最好用sigaction(),signal()不可靠; ??? 2. 通过函数sigaction指明标志SA_NOCLDWAIT来指定信号SIGCHLD的动作,这使得内核在调用者的子进程终止时不创建僵死进程。 ??? 3. 二次fork调用;??? * *
文档评论(0)