进程与线程
在早期的操作系统中并没有线程的概念,进程是拥有资源和独立运行的最小单位,也是程序执行的最小单位。后来,随着计算机的发展,由于进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了,于是就发明了线程。
线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的资源(Text,heap 和 global data 等)。
线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信
号等),某进程内的线程在其他进程不可见;
调度和切换:线程上下文切换比进程上下文切换要快得多
要注意的是,对于多线程来说,由于同一个进程空间中存在多个栈,任何一个空白区域被填满都会导致 stack overflow 的问题。
并行与并发
并发(Concurrency)是指同一时刻只能有一个任务得到执行,但多个任务被快速轮换执行,使得在宏观上有多个进程被同时执行的效果(宏观上并行)。其中,并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
并行(Parallelism)是指同一时刻有多个任务同时在执行。只有在多 CPU 的情况下,才能实现并行。
Linux 线程
在早期的类 Unix 系统中是没有线程概念, Linux 内核也只提供了 轻量级进程(light-weight process) 的支持,未实现线程模型。Linux 是一种 “多进程单线程” 的操作系统。Linux 本身只有进程的概念,而其所谓的 “线程” 本质上在内核里仍然是进程。
当 Linux 最初开发时,在内核中并不能真正支持线程。但是它的确可以通过 clone() 系统调用,将进程作为可调度的实体。这个调用创建了调用进程(calling process)的一个拷贝,这个拷贝与调用进程共享相同的地址空间。LinuxThreads 项目使用这个调用来实现在用户空间模拟对线程的支持。
不幸的是,这种方法有一些缺点,尤其是在信号处理、调度和进程间同步原语方面都存在问题。另外,这个线程模型也不符合 POSIX 的要求。在源码看来,就是 Linux 内核的 clone() 没有实现对 CLONE_PID 参数的支持。
|