全部博文(2759)
分类: LINUX
2013-04-02 09:06:53
Linux进程管理
1、什么是进程?
进程是处于执行器的程序,但进程并不仅仅局限于一段可执行程序代码,通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,当然还包括用来存放全局变量的数据段等。
2、程序与进程的区别?
程序是存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体。
进程是一个执行中的程序,它是动态的实体。
3、进程、用户线程和内核线程之间的区别?
4、进程描述符
① 进程描述符在内存里的组织形式
在2.6以前的内核中,各进程的task_struct存放在它们内核栈的尾端,这样可以只要通过栈指针就能计算出它的位置。但是随着进程描述符所占用的空间越来越大,Linux 通过slab分配器动态生成task_struct结构,所以只需在内核栈底创建一个新的结构struct thread_info,指向进程的task_struct结构。如下图所示:
② 进程状态(volatitle long state)
a. TASK_RUNNING
进程正在被CPU执行,或者已经准备就绪,随时可以执行。当一个进程刚被创建时,就处于TASK_RUNNING。
b. TASK_INTERRUPTIBLE
处于等待中的进程,待等待条件为真时被唤醒,也可以被信号或者中断唤醒。
c. TASK_UNINTERRUPTIBLE
处于等待中的进程,待资源有效时被唤醒,但不可以由其他进程通过信号或者中断唤醒。
d. TASK_STOPPED
进程中止执行。当接收到SIGSTOP和SIGTSTP等信号时,进程进入该状态,接收到SIGCONT信号后,进程重新回到TASK_RUNNING。
e. TASK_KILLABLE
Linux2.6.25新引入的进程睡眠状态,原理类似于TASK_UNINTERRUPTIBLE,但是可以被致命信号(SIGKILL)唤醒。
f. TASK_TRACED
正处于被调试状态的进程
g. TASK_DEAD
进程退出时(调用do_exit),state字段被设置为该状态。
③ 进程退出时的状态(int exit_state)
a. EXIT_ZOMBLE
僵死进程:表示进程的执行被终止,但是父进程还没有发布waitpid()系统调用来收集有关死亡的进程的信息。
b. EXIT_DEAD
僵死撤销状态:表示进程的最终状态,父进程已经使用wait4()或waitpid()系统调用来收集了信息,因此进程将由系统删除。
5、进程上下文与中断上下文的区别
用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递很多变量和参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存器值、变量等。所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。
硬件通过触发信号,导致调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。
6、进程创建
① 写时拷贝
a. 传统的fork()
直接把所有的资源复制给新创建的进程,这种实现过于简单并且效率低下,因为它拷贝的数据并不共享,更糟的情况是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都将前功尽弃。
b. 现在的fork()
使用写时拷贝页实现,内核并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。资源的复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享。
fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。
② fork()与vfork()的区别
除了不拷贝父进程的页表项外,vfork()系统调用和fork()的功能相同。
7、进程终结
当一个进程终结时,内核通过do_exit()释放掉与进程相关联的所有资源,进程不可运行并处于EXIT_ZOMBIE僵死状态。它占用的所有内存就是内核栈、thread_info结构和task_struct结构。在父进程获得已终结的子进程的信息后,使用wait4()或waitpid()系统调用将进程所持有的剩余内存释放。
8、孤儿进程
如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲,否则这些成为孤儿的进程就会在退出时永远处于僵死状态,白白地耗费内存。对于这个问题的解决办法是给子进程在当前进程组(指的是父进程组)内找一个线程作为父亲,如果不行,就让init做它们的父进程。