1. Linux中的进程与线程(1) 进程与线程的定义进程概念是在上个世纪60年代提出的,进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。进程具有两个基本属性:一是进程是一个可拥有资源的独立单位。二是进程是一个可被处理器独立调度的分配单位。这两个属性构成了程序并发执行的基础。为了使进程并发执行,操作系统还需具备对进程执行一些操作,比如创建进程、撤消进程以及进程的切换。在进行这些操作时,操作系统必须为之付出较多的时间开销。正因如此,在系统中进程不宜设置过多,进程间的切换也不宜频繁,从而限制了并发程度的进一步提高。为解决这一问题,人们想到将进程的两个基本属性分开,即对作为调度和分派的基本单位,不同时作为独立分配资源的单位;对拥有资源的单位,不对之进行频繁的切换。因而线程的思想便产生了。在许多的应用中,一些执行流之间具有内在的逻辑关系,涉及相同的代码或数据。如果将这些执行流放在同一个进程框架下,则这些执行流之间的切换便不涉及地址空间的变化,这也是线程产生的主要动力。引入线程的另一个推动力是线程能较好地支持对称多处理器系统(Symmetric Multiprocessor,SMP)。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。在面向线程的操作系统中,我们可以把进程看作是线程的容器,系统以进程作为资源分配的独立单位,以线程作为独立运行的单位。前面所定义的进程我们称为传统的进程,或者将其看作是只含有一个线程的进程。知乎作者pansz曾比喻进程线程如下:1、单进程单线程:一个人在一个桌子上吃菜。传统的进程,比如传统的UNIX系统。2、单进程多线程:多个人在同一个桌子上一起吃菜。比如Linux,Windows NT。3*、多进程单线程:一个人可以在不同的桌子上吃菜。一个线程可以从一个进程环境迁移到另一个环境,即允许线程轻松地在不同系统中移动。比如Ra(Clouds)和Enerald系统4*、多进程多线程:结合单进程多线程和多进程单线程的属性。比如TRIX系统。注:3和4是不常见的模型。(2) 线程和并发线程也称为轻量级进程,它是一种通过减少开销来提高操作系统性能的软件方法。每个线程只属于一个进程,进程外不能存在任何线程。每个线程代表一个单独的控制流。线程的优点有:
2. Linux线程(1) 实现原理线程的概念是上世纪80年代才引入的,所以在Unix系统的早期是没有线程的概念。Unix系统借助于进程机制实现线程,因此在Unix/Linux系统中,进程和线程关系密切,有时也称线程为轻量级进程(light-weight process)。创建线程和进程所使用的底层函数是一样的,都是clone()。从内核看进程和线程是一样的,都有各自不同的PCB,但是线程的PCB和进程的PCB指向内存资源的三级页表都是相同的,因此,进程可以蜕变成线程,每一个线程都有自己的函数调用,拥有自己的用户栈空间,内核区也有一个栈空间用来保存寄存器的值(系统为不同的线程分配CPU时间片,在不同的线程间切换)。(2) 进程与线程的地址空间对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。但是,线程不同!一个进程中的两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面,所以两个PCB共享一个地址空间。实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。如果复制对方的地址空间,那么就产出一个“进程”;如果共享对方的地址空间,就产生一个“线程”。因此,Linux内核是不区分进程和线程的,只在用户层面上进行区分。所以,线程所有操作函数pthread_*是库函数,而非系统调用。(3) 资源分配和CPU调度的最小单位当进程调用pthread_create函数后就蜕变成一个线程,经过多次pthread_create后就有了多个线程,而线程和进程的地位是一样的,当系统在分配时间片时会一视同仁。所以说线程是CPU调度的最小单位,而无论在一个进程中创建多少个线程,它们都共享一个同一个地址空间,所以说进程是资源分配的基本单位。3. Linux的线程和进程比较(1) 线程和进程中的全局变量当一个进程创建一个子进程后,父子进程在各自的地址空间中运行,因此,他们对全局变量的操作互不影响。而线程就不一样了,当一个线程创建一个子线程后,父子线程在同一个地址空间中运行,这就说明父子线程可共享全局变量,对全局变量的操作需要互斥,本节仅演示父子线程可共享变量,有关线程的互斥请看其他资料。下面举例说明。例1: 进程之间不共享全局变量运行结果如下: 可以看出,父子进程对变量a的操作互不影响。例2: 线程之间共享全局变量 运行结果: 可见,父子线程共享了全局变量a。 (2) 进程与线程控制原语对比
(3)多线程与多进程的区别
---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:操作系统学习,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |