操作系统------线程的概念/线程与进程的区别

线程的引入

        在“进程的概念”一文中,提到了进程的两个基本属性:

(1)进程是一个可拥有资源的基本单位。包括PCB,地址空间,页表,物理内存上的数据和代码等。

(2)进程同时又是一个可独立调度和分派的基本单位。每个进程都有唯一的一个PCB,操作系统通过PCB感知进程的存在,进而调度进程。

        为了使程序能够并发执行,操作系统必须:

(1)创建进程:为其分配资源和PCB等

(2)进程切换:需保留进程的上下文信息等

(3)销毁进程:撤销为进程分配的资源和PCB等

        进程作为一个资源的拥有者,在创建,切换,销毁的过程中,操作系统花费的时间比较长。所以必须限制创建的进程数,且进程的切换不能够太过频繁。从而限制了程序的并发执行效率。

        为了使程序能够更好的并发执行,操作系统将进程的而两个属性分离开。将拥有资源所有权的单位称为进程,而将调度和分派的单位称为线程。

线程的概念

         线程是在进程内部运行的比进程更细化的执行流。线程在进程内部运行是指在进程的地址空间内运行。

        在Linux中没有真正的线程,因为没有专门用来描述线程的结构体。它是用进程来模拟的,也就是用进程的PCB来描述线程的。如下图:


        CPU是根据PCB来调度的,所以说,一个PCB就相当于一个执行流。所以可以将一个PCB理解为一个线程(资源忽略不计)。

        而对于进程来说,它在创建时必有一个PCB,所以进程拥有至少一个执行流和资源(地址空间等)。进程拥有资源的多少是通过它的地址空间来看到的。

        在上图中,一个进程包括上述的4个PCB,虚拟地址空间,页表,物理内存等,可以将上述整张图都称为进程。而对于线程来说只有一个PCB和进程中的少量资源。所以可以说在上图所表示的进程中,共有4个PCB,所以有4个执行流,所以有4个线程。

        在CPU的眼里,一个PCB(进程描述符)就代表一个进程,所以说,Linux下的进程都是轻量级进程。它轻量在只包含一个PCB和少量的资源。

线程的资源

        一个进程中的多个线程的大部分资源是共享的:

(1)同一地址空间,由上图可知,多个线程均指向同一地址空间。所以如果在一个进程中定义了一个全局变量,那么该进程中的所有线程都可以看到该变量

(2)文件描述符表。它是以进程为单位进行分配的。当一个线程以只读的方式打开一个文件,与它处于同一进程的其他线程也可以读取该文件。

(3)各种信号的处理方式

(4)当前工作目录

(5)用户id和组id

        除了上述的共享资源外,个线程还拥有自己的一部分数据:

(1)线程id,用于唯一的标识该线程

(2)一组寄存器(私有上下文)。因为线程作为调度的实体,在切换时要保存当前的状态到寄存器中

(3)私有栈。用于保存该线程私有的局部变量等

(4)线程的运行状态:包括执行状态,就绪状态,阻塞状态

(5)信号屏蔽字

(6)errno

(7)调度优先级。各线程要被调度,就必须有优先级。

线程的实现方式

        线程有两种实现方式:用户级线程和内核级线程

1. 内核级线程

        在操作系统中,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的。而内核级线程也是在内核的支持下运行的。它们的创建,切换,销毁等都是在内核空间实现的。为了对内核级线程进行控制和管理,在内核空间内为每个线程设置了一个线程控制块(用PCB模拟实现)。内核根据该控制块而感知该线程的存在。

        内核级线程的优点:如果一个进程中的线程阻塞了,内核可以调度该进程中的其他内核级线程来运行。

        内核级线程的缺点:对于用户进程的线程来说,它是在用户空间运行的,而内核级线程的调度和管理是在内核实现的。所以当一个线程要切换到另一线程时,需要从用户态转到核心态进行。此时系统开销比较大。

2. 用户级线程

        用户级线程是在用户空间中实现的。对于线程的创建,切换,销毁等都无需内核的支持。即用户级线程是与内核无关的。可以说内核完全不知道用户级线程的存在。

        对于设置了用户级线程的系统,其调度仍然以进程为单位来进行的。

        用户级进程的优点:

(1)线程切换不需要转换到内核空间

(2)调度算法可以是进程专用的。

(3)用户级线程的实现与操作系统的平台无关

        用户级线程的缺点:

(1)当一个用户级线程执行一个系统调用时,不仅该线程会阻塞,该进程中的所有线程也会被阻塞。而对于内核级线程来说,该进程中的其他线程仍可以运行。

(2)CPU的调度是以进程为单位进行的。而对于内核级线程来说,是以线程为单位进行调度的。

Linux下的线程

        在Linux中,目前线程的实现时Native POSIX Thread Libary简称NPTL。在这种实现下,:每个用户级线程对应一个内核中的调度实体即内核级线程,也拥有自己的进程描述符(task_struct结构体)。 (关于该线程库的相关内容在“线程的控制”一文中介绍)

        在CPU的眼里,一个PCB(进程描述符)就代表一个进程,所以说,Linux下的进程都是轻量级进程。它轻量在只包含一个PCB和少量的资源。

线程与进程的区别

1. 进程是承担分配系统资源的基本实体。而线程是调度的基本单位。

2. 进程是系统中拥有资源的一个基本单位。而线程本身并不拥有资源,只有一点必不可少的,能保证其独立运行的资源。

3. 创建一个新线程的代价比创建一个新进程的代价小的多。创建一个进程需要创建PCB,地址空间,页表,分配物理内存上的数据等资源。而创建一个线程只需创建一个PCB,再给其分配少量的资源即可。

4. 线程之间的切换相对于进程的切换需要操作系统做的工作少的多。例如,线程之间进行切换时就不需要切换地址空间,而进程需要。

5. 销毁一个线程比销毁一个进程的代价小的多。销毁一个线程只需回收PCB和少量的资源,而销毁一个进程则需要回收该进程中的所有PCB即及其所拥有的所有资源。

6. 当一个程序运行起来后,一个线程出错,该线程所属的进程(包含该进程中的其他线程)全部挂掉。系统回收进程资源。而一个进程出错,不会影响其它进程。所以说,进程更安全,线程更方便。

7. 线程之间的大部分资源都是共享的。而进程之间是独立的,所以线程之间相对于进程之间对临界资源的互斥与同步操作需要的更多。




猜你喜欢

转载自blog.csdn.net/sandmm112/article/details/80069020