定义
计算机上所有可运行的软件,通常也包括操作系统,被组织成若干顺序进程,简称进程。
cpu在进程之间来回切换,每个进程拥有它自己的虚拟cpu。
每个进程有一个逻辑计数器,当程序运行时,它的逻辑计数器被装入到物理计数器,实际上只有一个物理计数器。
创建进程
在unix系统中只有一个系统调用可以用来创建新的进程:fork。这个系统调用会创建一个与调用进程相同的副本。通常,子进程会修改其内存映像,并运行一个新的程序。
例:
在shell中执行sort命令,shell会创建一个子进程,和shell相同,然后更改内存映像,执行sort程序。
在unix中,创建进程之后,父进程和子进程有不同的地址空间,其中有两种可能。
- 父进程和子进程的地址空间一部分相同,一部分不同,相同的地址空间是不可更改的,不同的地址空间是可以更改的。相同地址空间也就是共享的。
- 父进程和子进程的地址空间相同,但是如果子进程需要写入数据,此时写时复制,也就是说如果需要修改共享内存中的数据,修改之前复制一份。
进程的层次结构
在unix中进程和它的所有子进程以及后裔共同组成一个进程组。
在windows中父进程得到一个令牌,可以操纵子进程,但是也可以把此令牌传送给其它进程。
进程的状态
运行、阻塞、就绪。
进程的调度过程
调度进程需要先将硬件中的程序计数器压入进程中,再将硬件中装入新的程序计数器,保存寄存器的值,设置新的堆栈,中断服务例程运行,调度器决定下一个运行的进程,开始运行当前的进程。
线程
对于cpu密集型的多个线程,并不能提高运行的效率,但如果存在大量的i/o处理,拥有多个线程允许重叠运行,会加快运行速度。
多个线程共享一个地址空间和其他资源。
由于共享一个地址空间和其他资源,所以cpu在切换相同进程的不同线程时,速度更快。
线程的状态
就绪、阻塞、运行
创建线程
新创建的线程标识符会作为函数值返回。
用户空间实现线程
用户空间实现多线程,内核并不知道有多个线程,每个进程有专用的线程表,记录线程的属性。
线程本身并没有调度的概念,如果不是外界干预,一个线程会一直运行至该线程结束。
在用户空间中,如果一个线程阻塞,调用一个过程,会检测该线程是否必须进入阻塞状态,如果必须,则该过程进行线程的调度,把当前的线程的一些状态进行存储,并调用其他线程。
内核中实现线程
内核中实现线程,多个进程有一个统一的线程表在内核中,供内核调度等其他使用。
当一个线程阻塞时,内核根据选择,可以运行同一个进程中的其它线程。
内核调度线程过程
内核了解到一个线程阻塞之后,内核通知该线程所在的进程。
收到该通知后,运行时系统就会将当前线程标记成阻塞状态,并在线程表中查找就绪状态的线程,设置寄存器,并运行。
弹出式线程
一个消息到达导致西戎创建一个处理该消息的线程,这种线程称为弹出式线程。