学习linux内核设计与实现第三章
——进程管理
1、 进程
进程是处于执行期的程序(目标码存放在某种存储介质上)。除可执行的程序代码外,进程还包括其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,当然还有用来存放全局变量的数据段。
线程是在进程中活动的对象。每个线程都拥有一个独立的程序计数器、进程栈和一组进程寄存器。内核调度的对象是线程,而不是进程。对linux系统而言,线程和进程并没有特别区分,线程只不过是一种特殊的进程罢了。
在现代操作系统中,进程提供两种虚拟机制:虚拟处理器和虚拟内存。线程间可以共享虚拟内存,但每个都拥有各自的虚拟处理器。
进程是处于执行期的程序以及相关资源的总称。
创建进程的fork()系统调用:fork()系统调用从内核返回两次:一次回到父进程,另一次回到新产生的子进程。
2、进程描述符及任务结构
内核把进程的列表存放在叫做任务队列的双向循环链表中,链表中的每一项都是类型为task_struct、称为进程描述符的结构,task_struct内包含了内核管理一个进程所需要的所有信息。
系统调用和异常处理程序是对内核明确定义的接口。进程只有通过这些接口才能陷入内核执行——对内核的所有访问都必须通过这些接口。
3、进程创建
1)首先fork()通过拷贝当前进程创建如意阁子进程。子进程与父进程的区别仅仅在于PID(每个进程唯一)、PPID(父进程的进程号,子进程将其设置为被拷贝进程的PID)和某些资源和统计量。exec()函数负责读取可执行文件并将其载入地址空间开始运行。
2)写时拷贝:一般在调用fork()函数创建完子进程后,内核会有意选择子进程首先执行。(虽然内核想让子程序先运行)因为一般子进程都会马上调用exec()函数,这样可以避免写时拷贝的额外开销,如果父进程首先执行的话,有可能会开始向地址空间写入。
3、线程
线程被视为一个与其他进程共享某些资源的进程。(线程对很多操作系统来来说是一种轻量级进程,相对于重量级的进程,线程被抽象为耗费较少资源,运行迅速的执行单元。而对linux来说,线程技术只是一种进程间资源共享的手段(linux的进程本身就够轻量了)。)。