OS之《线程管理》
进程是系统资源分配的最小单位,线程是最小的执行单位。
然而,现在的高级设计底层还是基于这个理论基础实现的。比如java的线程,还有最新版本的JDK的协程都是在为了更好的让CPU执行任务。
线程是为了使用多CPU提高笑了
为什么一定要使用线程?
- 线程是处理机调度的基本单位。cpu进行任务调度的时,进程需要现场保护,保存大量的寄存器的数据,而线程只需要保护少数寄存器的数据。
- 并发性。一个进程中的多个线程是可以并发执行。更快
- 拥有资源。进程是作为资源分配的基本单位。pcb创建时,申请了需要的所有资源,当然这些资源在线程中是可以共享的。线程不需要拥有所有资源,子需要有能保证线程独立运行的资源就好。比如:TCB,程序计数器,状态参数和返回地址等响应的寄存器和堆栈。所有线程能共享进程拥有的IO设备、信号量、内存空间、打开的文件等资源
- 独立性。进程管理中,进程是独立的。独立运行,独立的内存空间地址等。但线程中更多的是共享。多线程多数是为了配合更快的完成任务。
- 系统开销。线程的创建比进程快50倍,线程的切换快5倍。因为多个线程具有相同的地址空间(进程的地址),所以线程的通信也要快并且简单。很多OS中线程的切换、同步、通信不需要OS内核干预。
- 多处理机并行执行。
线程三态:执行、就绪、阻塞
线程控制块TCB都包含哪些内容
- thread表示符
- 一组寄存器,包含程序计数器、状态寄存器、通用寄存器
- 线程运行状态
- 优先级
- 线程专有存储区域,用于线程切换的时现场保护使用
- 信号屏蔽
- 堆栈指针。每一个线程设置一个堆栈用于保存方法调用过程中,局部变量和返回地址。在TCB中必须设置两个指针。一个执行用户堆栈指针,一个执行核心栈指针。当前程序运行在用户太态时,使用用户自己的堆栈保持局部变量和返回地址。当陷入内核态时,使用内核态的栈保存局部变量和返回地址。
多线程操作系统中的进程属性
- 进程是拥有资源的基本单位。除了拥有打开的设备、文件等资源外,还有一张由核心进程维护的地址映射表,该表用于实现用户程序的逻辑地址和物理地址映射关系。
- 多线程可以并发执行。java就是最典型的例子。
- 进程不再是可执行的实体。线程才是可执行的最小单元。但是os对进程的操作会对进程中的线程起作用。比如对进程执行挂起时,会将进程中的所有线程全部挂起。os把进程激活时,会把该进程中的所有线程也激活。
线程的实现方式由两种
- 内核级线程:不论进程还是线程,都是通过内核控制其创建,阻塞,撤销,切换的,为了实现oS对其控制, 所以会每一个线程对应的TCB或者是PCB进行调度的。这种实现方式有以下优势:
- 在多处理机下,内核能同时调度同一进程中的多个线程到处理机并行执行。
- 如果进程中的一个线程被阻塞了,内核还可以调用该进程中的其他线程到处理机运行
- 内核支持线程具有很小的数据结构和堆栈。线程的切换快,开销小。
- 内核本省也可以使用多线程技术
- 它的明显的缺点是:对用户线程来讲,线程的切换,调度等开销比较大,是因为变态导致的。
- 用户级线程:用户级线程是在用户空间下实现的。对应的线程的创建、撤销、同步、通信等功能都是在用户态实现的,不需要os内核参与,既用户级线程是和内核无关的。这些TCB都是在用户态存在的,线程所执行的操作也不需要内核干预,因而内核是感受不到用户线程的存在的。优势如下:
- 线程在用户空间下进行切换,创建,撤销等一系列操作,是不需要切换到内核态的。因为一个用户太的进程拥有了该进程下是所有的线程TCB的,在用户太就能完成调度和管理。从而减小的开销
- 调度算法可以是进程专用的。在不干扰OS调度的情况下,不同的进程可以根据选择的不同的调度算法,对自己的线程进程管理和调度,和OS的低级调度算法无关。
- 用户级线程的实现和OS无关,因为对线程的管理的代码是属于用户程序的一部分,所有的应用程序都可以对之进行共享。可以理解是一个特定的接口,具体实现是有各个应用自己去实现的。因此,用户级线程甚至可以在不支持线程机制的操作系统平台上实现。
用户级线程的缺点也很明显
- 如果遇到基于进程机制的OS中,大多数的系统调用会将进程阻塞,因此,当一个线程执行一个系统调用的时候,不仅该线程会被阻塞,整个进程内的所有线程都会阻塞。而在内核支持线程的方式中,该进程中的其他线程还是可以继续运行的。
- 在单纯的用户级线程实现方式中,多线程应用不能利用多处理机。内核每次给进程分配一个cpu,因此进程中只有一个线程能执行,其他只能等待。
组合方式:
把用户多线程和内核多线程结合起来。就会出现n:N的关系。当发生系统调用的时候,就会将用户线程和内核线程进行映射。内核控制线程的数据可以根据应用进程和系统的不同而变化
线程的实现方式:
内核支持线程的实现
内核支持以直接使用系统调用,操作简单。
用户级线程的实现
所有用户级线程都有一个相同的结构,他们是在一个中间系统上现。现在有两种中间系统实现。线程的调度执行也很简单,只需要有对应的栈指针和程序计数器就可以完成线程执行。运行时系统:它是一个控制线程对系统函数调用时的控制,有这么一个运行时系统,将对系统调用的函数包装一下,放在用户态空间下,用户线程在调用的时候不需要变态等操作,隔离了对内核态的依赖。使得用户线程和内核无关。
内核控制线程:它是一种轻型进程(LWP,light weight process),每一个进程都可以拥有多个lwp,同用户级线程一样,都有自己的TCB,其中包括有线程标识,优先级,状态,还有栈和局部存储区等。LWP可以共享进程所拥有的资源。它可以通过系统调用来获得内核提供服务。这样,当一个用户级别线程只要和一个LWP连接,就能过去的内核对支持。一个系统中用户级线程可能很多,不可能实现每一个线程都有一个LWP和其对应,就对LWP做了池化管理。用户级线程只要能连接上池中的任意线程,就能实现对内核的调用。这样也一定程度上实现了多路复用一个LWP。用户可以通过LWP连接到内核,但内核只能看到LWP,看不到用户级线程。也实现了用户线程和内核线程之间的隔离。
OS之《线程管理》的更多相关文章
- 《Tsinghua os mooc》第17~20讲 同步互斥、信号量、管程、死锁
第十七讲 同步互斥 进程并发执行 好处1:共享资源.比如:多个用户使用同一台计算机. 好处2:加速.I/O操作和CPU计算可以重叠(并行). 好处3:模块化. 将大程序分解成小程序.以编译为例,gcc ...
- OS之进程管理 --- 死锁
什么是死锁 在正常操作模式下,进程按如下顺序来使用资源: 申请:进程请求资源 使用:进程对资源进行操作 释放:进程释放资源 当一组进程中的每一个进程度在等待一个事件,而这事件只能有一组进程的另一个进程 ...
- [OS] 死锁相关知识点以及银行家算法详解
因此我们先来介绍一下死锁: 死锁特征 当出现死锁时,进程永远不能完成,并且系统资源被阻碍使用,阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,先深入讨论一下死锁的特征. ·必要条件 (1)互 ...
- OS | 死锁
死锁的四个条件 互斥 占用等待 非剥夺 循环等待 死锁的解决方案 死锁预防 间接预防:防止前三个条件中的任何一个的发生 直接预防:防止循环等待的发生 死锁避免 进程启动拒绝:不启动任何一个可能发生死锁 ...
- 查看w3wp进程占用的内存及.NET内存泄露,死锁分析
一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...
- java 利用ManagementFactory获取jvm,os的一些信息--转
原文地址:http://blog.csdn.net/dream_broken/article/details/49759043 想了解下某个Java项目的运行时jvm的情况,可以使用一些监控工具,比如 ...
- Oracle死锁
当两个或多个用户相互等待锁定的数据时就会发生死锁,这时这些用户被卡在不能继续处理业务,oracle可以自动检测死锁并解决他们,通过回滚一个死锁中的语句,释放锁定的数据,回滚的话会遇到ora-00060 ...
- 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样...
出错提示: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中增加了42种非常强大的调试助手 ...
- 查找原始MySQL死锁ID
转载地址:http://yueliangdao0608.blog.51cto.com/397025/1180917 如果遇到死锁了,怎么解决呢?找到原始的锁ID,然后KILL掉一直持有的那个线程就可以 ...
- mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例
今天,某个环境又发生了死锁,如下: *** (1) TRANSACTION:TRANSACTION 735307073, ACTIVE 0 sec insertingmysql tables in u ...
随机推荐
- Servlet——Request对象-请求数据&请求参数
Request 继承体系 1.Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中 2.使用request对象,查阅javaEE ...
- 痞子衡嵌入式:MCUBootUtility v6.3发布,支持获取与解析启动日志
-- 痞子衡维护的 NXP-MCUBootUtility 工具距离上一个大版本(v5.3.0)发布过去一年了,期间痞子衡也做过三个版本更新,但不足以单独介绍.这一次痞子衡为大家带来了全新重要版本v6. ...
- QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家
QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家 简介 本文将介绍QT数据可视化框架编程实战之三维曲面图,本文通过构造一个数据实时变化的三维曲面图的应用实例来展示Q ...
- Java Web 拾遗
许是年纪大了,老是回忆起以前的点点滴滴.翻看当初的代码,如同偶遇多年未见的前女友,曾经一起深入交流的情谊在颔首之间消散,令人烦躁. 今天就来聊聊老生常谈的 Java Web 开发.缘于一个简单的Spr ...
- [Tkey] A decorative fence
还是看看简单而富有美感的爆搜吧 #include<bits/stdc++.h> using namespace std; #define int long long #define tes ...
- 使用duxapp开发 React Native App 事半功倍
Taro的React Native端开发提供了两种开发方式,一种是将壳和代码分离,一种是将壳和代码合并在一起开发 壳是用来打包调试版或者发版安装包使用的 代码是运行在壳上的js代码 Taro壳子的代码 ...
- 能用到“退休”的 600条 Linux 命令,可以解决日常99%的问题~
1.基本命令 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 (SMBIOS / DMI) hdparm -i /dev/ ...
- CocoaPods常用的命令行以及安装方法
1.新建一个Xcode工程,使用终端cd到工程目录下 2.创建Podfile文件 pod init ,之后就可以在项目目录里看到一个Podfile文件 3.打开Podfile文件:open Podfi ...
- 基于QToolButton封装,解决Icon不能设置hover和press态的问题
1 #pragma once 2 #include <QToolButton> 3 #include <QBoxLayout> 4 #include <QLabel> ...
- 在 Kubernetes 中运行 Locust 与 Selenium:安装 Chrome 和 ChromeDriver
在现代软件开发中,性能和用户体验是至关重要的,而负载测试和自动化测试可以帮助我们实现这一目标.在本文中,我们将讨论如何在 Kubernetes 环境中运行 Locust 和 Selenium,并详细介 ...