OS之《线程管理》

进程是系统资源分配的最小单位,线程是最小的执行单位。
然而,现在的高级设计底层还是基于这个理论基础实现的。比如java的线程,还有最新版本的JDK的协程都是在为了更好的让CPU执行任务。

线程是为了使用多CPU提高笑了

为什么一定要使用线程?

  1. 线程是处理机调度的基本单位。cpu进行任务调度的时,进程需要现场保护,保存大量的寄存器的数据,而线程只需要保护少数寄存器的数据。
  2. 并发性。一个进程中的多个线程是可以并发执行。更快
  3. 拥有资源。进程是作为资源分配的基本单位。pcb创建时,申请了需要的所有资源,当然这些资源在线程中是可以共享的。线程不需要拥有所有资源,子需要有能保证线程独立运行的资源就好。比如:TCB,程序计数器,状态参数和返回地址等响应的寄存器和堆栈。所有线程能共享进程拥有的IO设备、信号量、内存空间、打开的文件等资源
  4. 独立性。进程管理中,进程是独立的。独立运行,独立的内存空间地址等。但线程中更多的是共享。多线程多数是为了配合更快的完成任务。
  5. 系统开销。线程的创建比进程快50倍,线程的切换快5倍。因为多个线程具有相同的地址空间(进程的地址),所以线程的通信也要快并且简单。很多OS中线程的切换、同步、通信不需要OS内核干预。
  6. 多处理机并行执行。

线程三态:执行、就绪、阻塞

线程控制块TCB都包含哪些内容

  1. thread表示符
  2. 一组寄存器,包含程序计数器、状态寄存器、通用寄存器
  3. 线程运行状态
  4. 优先级
  5. 线程专有存储区域,用于线程切换的时现场保护使用
  6. 信号屏蔽
  7. 堆栈指针。每一个线程设置一个堆栈用于保存方法调用过程中,局部变量和返回地址。在TCB中必须设置两个指针。一个执行用户堆栈指针,一个执行核心栈指针。当前程序运行在用户太态时,使用用户自己的堆栈保持局部变量和返回地址。当陷入内核态时,使用内核态的栈保存局部变量和返回地址。

多线程操作系统中的进程属性

  1. 进程是拥有资源的基本单位。除了拥有打开的设备、文件等资源外,还有一张由核心进程维护的地址映射表,该表用于实现用户程序的逻辑地址和物理地址映射关系。
  2. 多线程可以并发执行。java就是最典型的例子。
  3. 进程不再是可执行的实体。线程才是可执行的最小单元。但是os对进程的操作会对进程中的线程起作用。比如对进程执行挂起时,会将进程中的所有线程全部挂起。os把进程激活时,会把该进程中的所有线程也激活。

线程的实现方式由两种

  • 内核级线程:不论进程还是线程,都是通过内核控制其创建,阻塞,撤销,切换的,为了实现oS对其控制, 所以会每一个线程对应的TCB或者是PCB进行调度的。这种实现方式有以下优势:
  1. 在多处理机下,内核能同时调度同一进程中的多个线程到处理机并行执行。
  2. 如果进程中的一个线程被阻塞了,内核还可以调用该进程中的其他线程到处理机运行
  3. 内核支持线程具有很小的数据结构和堆栈。线程的切换快,开销小。
  4. 内核本省也可以使用多线程技术
  5. 它的明显的缺点是:对用户线程来讲,线程的切换,调度等开销比较大,是因为变态导致的。
  • 用户级线程:用户级线程是在用户空间下实现的。对应的线程的创建、撤销、同步、通信等功能都是在用户态实现的,不需要os内核参与,既用户级线程是和内核无关的。这些TCB都是在用户态存在的,线程所执行的操作也不需要内核干预,因而内核是感受不到用户线程的存在的。优势如下:
  1. 线程在用户空间下进行切换,创建,撤销等一系列操作,是不需要切换到内核态的。因为一个用户太的进程拥有了该进程下是所有的线程TCB的,在用户太就能完成调度和管理。从而减小的开销
  2. 调度算法可以是进程专用的。在不干扰OS调度的情况下,不同的进程可以根据选择的不同的调度算法,对自己的线程进程管理和调度,和OS的低级调度算法无关。
  3. 用户级线程的实现和OS无关,因为对线程的管理的代码是属于用户程序的一部分,所有的应用程序都可以对之进行共享。可以理解是一个特定的接口,具体实现是有各个应用自己去实现的。因此,用户级线程甚至可以在不支持线程机制的操作系统平台上实现。

用户级线程的缺点也很明显

  • 如果遇到基于进程机制的OS中,大多数的系统调用会将进程阻塞,因此,当一个线程执行一个系统调用的时候,不仅该线程会被阻塞,整个进程内的所有线程都会阻塞。而在内核支持线程的方式中,该进程中的其他线程还是可以继续运行的。
  • 在单纯的用户级线程实现方式中,多线程应用不能利用多处理机。内核每次给进程分配一个cpu,因此进程中只有一个线程能执行,其他只能等待。

组合方式:
把用户多线程和内核多线程结合起来。就会出现n:N的关系。当发生系统调用的时候,就会将用户线程和内核线程进行映射。内核控制线程的数据可以根据应用进程和系统的不同而变化

线程的实现方式:

  • 内核支持线程的实现

    内核支持以直接使用系统调用,操作简单。

  • 用户级线程的实现
    所有用户级线程都有一个相同的结构,他们是在一个中间系统上现。现在有两种中间系统实现。线程的调度执行也很简单,只需要有对应的栈指针和程序计数器就可以完成线程执行。

    运行时系统:它是一个控制线程对系统函数调用时的控制,有这么一个运行时系统,将对系统调用的函数包装一下,放在用户态空间下,用户线程在调用的时候不需要变态等操作,隔离了对内核态的依赖。使得用户线程和内核无关。

    内核控制线程:它是一种轻型进程(LWP,light weight process),每一个进程都可以拥有多个lwp,同用户级线程一样,都有自己的TCB,其中包括有线程标识,优先级,状态,还有栈和局部存储区等。LWP可以共享进程所拥有的资源。它可以通过系统调用来获得内核提供服务。这样,当一个用户级别线程只要和一个LWP连接,就能过去的内核对支持。一个系统中用户级线程可能很多,不可能实现每一个线程都有一个LWP和其对应,就对LWP做了池化管理。用户级线程只要能连接上池中的任意线程,就能实现对内核的调用。这样也一定程度上实现了多路复用一个LWP。用户可以通过LWP连接到内核,但内核只能看到LWP,看不到用户级线程。也实现了用户线程和内核线程之间的隔离。

posted @   Eular  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示