`
CharlesCui
  • 浏览: 416392 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

<<LINUX内核完全注释>>阅读笔记------进程初始化及进程调度

阅读更多
进程初始化:
在内核态下运行的进程不能被其他进程抢占,内核在执行临界区代码时会禁止一切中断。
任务0是最原始的进程,宏move_to_user_mode对该进程从内核态移动到用户态,从而完成任务0的“净身”。
为何要“净身“?因为任务0是一切有系统fork()创建的进程的模板,都是通过复制任务0得到的。
fork()一个新进程时,新进程的任务数据结构还没有完成时,该进程状态为不可中断的等待状态TASK_UNINTERRUPTIBLE。
fork.c中sys_fork()调用了两个函数:find_empty_process()和copy_process(),这就是进程创建的两个步骤:进程表中寻找空的位置,然后copy父进程。
新进程创建时的Copy On Write技术:子进程和父进程在最初是同一个内存页面,只有当子或父进程有一个写操作时,系统才会为
执行写操作的进程分配独立的内存页面。
fork()结束前,新进程被置为可运行状态,同时返回新进程号。
fork()和extc()完全不同,fork()纯复制父进程的代码和数据区,exec()将清空父进程的代码和数据区,然后再加载exec()
参数指明的代码和数据并执行。

进程调度:
Linux进程是抢占式的,被抢占的进程仍然出于TASK_RUNNING状态,进程的抢占发生在进程处于用户态执行阶段,
在内核态执行时是不能被抢占的。在内核模式下运行时,如果任务没有主动sleep(),不会让内核切换任务。
进程切换,简而言之就是tss的切换。
终止进程:,这里有很多要注意的。
1、用户程序调用exit()时,内核会执行do_exit(),该方法释放调用进程的内存页面,关闭打开的文件,同步所有i节点。
2、如果进程有子进程,则init进程作为该进程所有子进程的父进程。
3、如果进程是会话头进程并且有控制终端,则释放控制终端,向该绘画的所有进程发送ISGHUP信号。比如Secrt关掉了一个窗口,该窗口
所有启动的进程都可能会被中断。
4、do_exit()之后,该进程状态为僵死状态TASK_ZOMBIE,同时向其父进程发送SIGCHLD。但如果父进程一直没有取得该子进程数据结构,则该子进程
的数据结构将一直保留。这就是僵尸进程的来源。
进程组:一个或者多个进程的集合。每个进程组都有唯一的进程组标识号gid,进程组有个组长,组长的进程pid等于进程组的gid。
管道就是一个进程组。

终端环境初始化:init--fork()-->agetty--exec()-->login--exec()-->shell
fork()和exec()是有很大区别的,init不可能将自己销毁。agetty和login分别做完终端初始化和验证之后就没必要存活了,所以用exec().

引导启动程序一章没看6
初始化进程一章没看前面的7
内核代码一章没看8
信号--第八章--307页,要看
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics