Linux内核设计与实现 第三章

                             Linux内核设计与实现 第三章

这一章介绍了Linux中进程的实现

进程描述符

Linux的进程信息放在一个叫进程描述符(task_struct)的结构中,各个进程描述符又组合成一个双向循环链表,即任务队列。这里的任务队列属于操作系统。对于每个进程来讲,在进程栈中还有另一个结构来描述本进程,这个结构往往就在栈顶或者栈底,叫thread_info。在改变进程状态或者进行其他操作时,我们可以先在进程地址空间找到thread_info然后再访问其task_struct。

                                         Linux内核设计与实现 第三章_第1张图片

进程状态

运行(可执行或者正在执行)R,阻塞(等待某些条件),不可中断(也是阻塞,不过在阻塞时不再接收别的信号,只等待自己阻塞的条件)被其他进程跟踪,停止执行。一共五种。

进程树

子进程可以直接访问父进程,父进程中有一个链表保存子进程,可以通过遍历链表访问子进程。所有进程有共同的祖先也就是init进程。所以访问系统中所有进程有两种方式:通过父子关系和通过任务队列。

进程创建

写时拷贝,也就是父进程在创建子进程时候直接共享所有资源,当子进程对进程栈做出改变的时候再把改变的这部分写到别的地方,此处属于子进程。fork()->clone()->do_fork()->copy_process():1。创建内核栈、threadinfo、taskstuct  2。确保资源没有超出。 3。taskstruct内很多成员需要被清零,比如一些计数  4。设置子进程状态  5。赋予子进程权限   6。分配pid   7。根据clone()的参数,copyprocess()共享打开的文件进程地址空间等信息。 8。copyprecess()返回一个指向子进程的指针。dofork函数让子进程开始运行。

线程

Linux中的线程比较有意思——只是某几个共享资源的进程。所以创建过程基本和进程一样,只是需要传递一些参数表明子进程和父进程共享资源。创建线程时候只需要向clone()传递一些参数标志来指明需要共享的资源。内核在后台做一些工作的线程,这些线程有一些特点,比如没有独立的地址空间,而且只能由其他内核线程创建(kthread_create方法)

进程终结

显示终结(exit)或者隐式终结:调用do_exit():1将taskstruct中的flag设置为PF_EXITING   2递减计数器,若为0则释放相应资源   3完成系统规定的退出动作  4调用exit_notify()给父进程发送信号并且给子进程重新寻找养父(防止变成孤儿进程),并把进程状态设置为Z。 5切换到新进程

删除进程描述符

尽管到目前为止,进程已经僵死了,但是系统仍然需要保留它的描述符以获得其信息。因此还需要删除它的进程描述符:父进程调用wait(),如果是孤儿进程,则永远处于僵死状态。

你可能感兴趣的:(Linux)