进程与线程(三)——线程的概念与实现

一 什么是线程?
进程中的一条执行流程。
有了线程,进程发生了一系列的变化。首先是(1)资源管理,包括地址空间(代码段,数据段):进程就是由来管理资源的:地址空间,打开的文件,访问的网络。(2)线程把进程的另一部分功能给拆出来了。 进程的执行功能,进程的执行状态交给了线程来管理。在运行的角度上来看,代码在执行的平台的执行流程,我们把它理解为一个线程,线程称成为了进程的重要组成部分。
进程主要完成资源的管理之外,需要有一系列的线程来完成执行的过程。进程里面存在多个线程,线程是共享进程提供的资源平台,属于同一个进程的线程共享进程所拥有的资源,可以直接访问进程的提供代码数据内存和文件等,线程之间的资源共享很容易实现了。

二 线程的组织结构:
1.线程控制块TCB
TCB和进程一样,线程具有自己的TCB线程控制块。但是和PCB有区别,TCB只负责管理执行流程相关的一系列的信息,包含执行的程序计数器PC,SP堆栈,寄存器。因为有不同的执行流,不同的控制流,需要通过寄存器来表示执行状态,这个是每一个线程所独立的信息。但是它的内存空间,比如说它的堆空间,它的代码段,它的数据段是所有线程所共享的。所以线程有各自独立的部分,有共享的部分。这是线程的特点。
缺点:因为可以共享,如果有一个线程写错了,它就有可能破坏其他的线程间的所共享的资源。一个线程把数据破坏了,其他线程也需要数据,其他线程也会导致崩溃的现象。安全可靠性没有办法保障。
这时候出现了适用性的问题
(1)高性能计算,使用线程
(2)Internet的服务,早期浏览器使用线程来实现。 现在CPU计算不是瓶颈,安全性要得到保障。chrome每一个网页用进程实现。

2. 线程=进程-共享资源 

单进程在执行的时候就只有一个控制流。多线程时,在进程空间里面会出现多个控制流,而且每个控制流的流程是不一样的:所以 线程需要独立的寄存器,堆栈,能够共享代码段,数据段,文件,网络资源等等 。如下图所示:现在有两类资源,一种是共享的,一种是独占的。 独占的资源和它的控制执行相关的,需要把这部分信息单独的保护起来,避免线程之间的状态的破坏。如果两个线程共享一个PC(程序计数器),那执行流程就不可能实现分别执行不同的流程。


了解:
Context————上下文
进程共享CPU,停止当前进程,并调度其他进程的切换叫做上下文切换。 
切换要用到的寄存器,寄存器是和我们紧密相连的。PC,栈指针寄存器,在切换时要保存到PCB。恢复时又重新取出来,重新赋值,使得接下来CPU继续执行。
上下文切换的开销越小越好,且所有信息都与硬件紧密相连,所以OS中实现是用汇编代码。

三 线程和进程的比较(重要)

1.进程是资源的分配单位(内存,打开的文件,网络等),线程是CPU调度单位,CPU是一种特殊的资源,主要强调的是控制流所必要的相关的信息。
2.进程是一个完整的资源平台,而线程是独立了必不可少的资源,这个资源包含寄存器和堆栈。
3.线程同样具有就绪、运行、阻塞状态。 和进程的状态是一样的。在这里我们把进程的功能做了切分。把这部分的功能给了线程。
4.线程可以实现并发执行的时间和空间的开销。
比如:
(1)线程的创建施加比进程要短——因为进程在创建过程中,还需要去创建其他一些管理的信息,比如内存管理,打开的文件管理。而线程在创建的时候,直接重用进程管理好的资源,所以,创建时间会短。
(2)同理,线程的销毁时间也要短——因为它不需要考虑资源的释放问题。
(3)另一方面,在做切换的时候呢,在同一进程中的线程切换也会很快。因为线程具有同一个地址空间, 属于同一进程的线程,拥有同一页表。在切换的时候,不需要切换内存管理所需要的页表。而对于进程而言,我们要切换进程的话, 需要把页表也要切换掉 ,而切换页表的开销是比较大的。因为涉及到要访问的地址空间是不一样的,很多cache信息,TLB的信息,硬件的信息都会无效,需要重新加载,开销较大。但是,线程切换的时候,共享同一页表,所有的信息可以重用,不需要有缺失,不需要做失效处理,效率会很高。
(4)另一方面,同一进程中的线程,它共享了进程包含的资源,在做线程之间的数据传递的时候,就不需要通过内核了,直接通过内存地址可以访问到,使得线程之间的数据交换的效率会很高。
综上所示,线程在执行过程中,它的时间效率,空间效率比进程高。

四 线程的实现方式

1.内核支持线程KST(Kernel Supported Threads)

内核线程切换比较快,切换开销小。

内核支持线程,对用户的线程而言,只要完成一次线程切换,需要从用户态到内核态的变换,开销相对于前面的用户管理开销会大一些


2.用户级线程ULT(User Level Threads)

用户线程:用户态的库完成了对线程控制的管理,它的线程控制块在库里面实现的。对OS而言,它看不到TCB,它只能看到我们的进程——整个进程的信息操作系统可以看到,但是进程里面的线程信息由我们的线程管理库来实现的,线程信息操作系统看不到。所以说整个线程的调度和管理, 操作系统不直接参与,而是由我们的线程库来完成。
操作系统感知不到线程,只能感知进程,只能把进程阻塞,那么所以属于进程的线程也会被跟着阻塞。
用户态的线程库没有办法打断当前用户的线程的执行,它没有这个特权,但是操作系统有——操作系统会管理中断,一旦会产生中断之后, CPU的控制权就落在了操作系统手里了,就可以对中断进行进行一步的处理,特别是时钟中断——可以来完成强制的切换把线程停止,给其他的线程执行。但是我们的线程库,用户态没有这个能力,如果用户线程不主动放弃CPU的使用权,其他线程也无法运行,这是用户线程的缺点。

3.组合方式: 轻量级进程

LWP作为一个接口来使用,LWP可以把用户线程和内核线程连接起来。内核看不到用户进程,但是用户进程可以通过LWP访问内核。


用户线程与内核线程间,可以是多对一,一对一,多对多

多对一:

一对一:

多对多:




猜你喜欢

转载自blog.csdn.net/weixin_37864819/article/details/78453566
今日推荐