一、进程、线程和轻量级进程
1、进程
一个进程在操作系统中通常指处于执行状态程序的一个实例,你也可以理解为用来描述程序已经执行到什么阶段所用数据结构的集合。
进程有些属性与人类相似:一个进程一旦被创建,他的生命周期或长或短,他可以选择性创建一个或者多个子进程,也可以不创建任何子进程,但最终都会死亡。与人类有一点不同的是,进程没有性别之分,每个进程只有一个父进程。
从内核的角度来看,进程是用于管理系统资源如何分配的一个实体。
当一个进程被创建,它几乎和它的父进程一样,它复制父进程地址空间,执行与父进程相同的代码,它是从紧接着用于创建该进程的系统调用的下一条指令开始执行的,尽管父进程与它共享同样的代码段,但是他们的数据(stack and heap)是独立的。因此子进程对数据的修改,父进程是不可见的。
2、线程
早期Unix内核采用这种简单模型,但是现代操作系统支持多线程应用------用户程序有多个相对独立的执行流,共享很大部分数据结构。在这样的系统中,一个进程是由多个线程组成,每个线程对应一个执行流。
早期Linux内核不支持多线程应用,从内核来看,一个多线程应用程序仅仅只是一个普通进程,多线程应用程序的多个执行流全部在用户空间被创建,被处理,被调度。
3、轻量级进程
但是这样的多线程应用程序实现并不令人非常满意,比如:假设一个国际象棋程序使用两个线程,一个用来控制棋盘图形,等待人类玩家的移动棋子,并展示计算机走了哪一步,而另一个线程考虑如何走下一步。当第一个线程等待人类玩家移动时,第二个线程应该持续运行,以利用人类玩家思考的时间。但是,如果这个程序仅仅只是一个进程,那么第一个线程就不能调用进程睡眠系统调用,以等待人类玩家行动,否则,第二线程也将被阻塞,为此,第一个线程必须使用复杂非阻塞的技术来保证程序继续运行。
Linux内核使用轻量级进程来支持多线程应用程序,两个轻量级进程可以共享一些资源,比如地址空间,打开的文件等等,无论何时,一个轻量级进程修改了一个共享资源,其他轻量级进程可以立即发现这个修改,当然,当两个轻量级进程共同访问同一个共享资源时,必须处理同步问题。
因此Linux内核实现支持多线程应用程序的最直接方式就是将一个轻量级进程与一个线程关联起来,通过共享相同的地址空间,打开文件等等资源,来达到线程共享应用程序使用的数据结构,同时,每个线程可以独立被调度,因此当一个线程进入睡眠时,其他线程依然可以保持运行。
参考资料:《深入理解Linux内核》
《understanding the linux kernel》 |