(学习笔记-进程管理)线程

news2024/9/20 15:05:09

在早期的操作系统都是以进程为独立运行的基本单位,直到后面,计算机科学家们提出了更小的能独立运行的基本单位:线程


 

为什么使用线程?

举个例子,假设要编写一个视频播放软件,那么软件功能的核心模块有三个:

  • 从视频文件中读取数据
  • 对读取的数据进行解压缩
  • 把压缩后的视频数据播放出来

对于单进程的实现方式:

 对于单进程的这种方式,存在以下问题:

  • 播放出来的画面和声音会不连贯,因为当CPU能力不够强的时候, Read 的时候可能进程就等在这了,这样就会导致等半天才进行数据解压和播放
  • 各个函数之间不是并发执行,影响资源的使用效率

那改成多进程的方式:

 对于多进程的这种方式,依然会存在问题:

  • 进程之间如何通信,共享数据?
  • 维护进程的系统开销较大,如创建进程时,分配资源、建立PCB;终止进程时,回收资源、撤销PCB;进程切换时,保存当前进程的状态信息;

那到底如何解决呢?需要有一种新的实体,满足以下特性:

  • 实体之间可以并发运行
  • 实体之间共享相同的地址空间

这个新的实体,就是线程(Thread),线程之间可以并发运行且共享相同的地址空间。


什么是线程?

线程是进程当中的一条执行流程。

同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。

 线程的优缺点?

线程的优点:

  • 一个进程中可以同时存在多个线程
  • 各个线程之间可以并发执行
  • 各个线程之间可以共享地址空间和文件等资源

线程的缺点:

  • 当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃(这里针对C/C++语言)。

举个例子,对于游戏的用户设计,则不应该使用多线程的方式,否则一个用户挂了,会影响其他同个进程的线程。


线程和进程的比较

线程和进程的比较:

  • 进程是资源(包括内存、打开的文件等)分配的单位,线程是CPU调度的单位
  • 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈
  • 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系
  • 线程能减少并发执行的时间和空间开销

对于线程相比进程能减少开销,体现在:

  • 线程的创建时间比进程快,因为进程在创建的过程中还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会设计这些资源管理信息,而是共享它们
  • 线程的终止时间比进程快,因为线程释放的资源相比进程要小很多
  • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存空间),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候就不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的
  • 由于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了

所以不管是时间效率还是空间效率,线程都比进程高。


线程的上下文切换

在前面我们知道了进程与线程最大的区别在于:线程是调度的基本单位,而进程则是资源拥有的基本单位

所谓操作系统的任务调度,实际上的调度对象是线程,而进程只是给线程提供了虚拟内存、全局变量等资源。

对于线程和进程,可以理解为:

  • 当进程只有一个线程时,可以认为进程就等于线程
  • 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时是不需要修改的

另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换的时候也是需要保存的。

线程上下文切换的是什么?

这还得看线程是不是属于同一个进程:

  • 当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换一样
  • 当两个线程属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据

所以,线程的上下文切换要比进程开销小很多。


线程的实现

主要有三种线程的实现方式:

  • 用户线程:在用户空间实现的线程,不是由内核管理的线程,是由应用层面的线程库来完成线程的管理,对于用户线程的存在,内核无法感知。
  • 内核线程:在内核中实现的线程,是由内核管理的线程
  • 轻量级进程:在内核中来支持用户的线程

用户线程和内核线程的对应关系

首先,第一种关系是多对一的关系,也就是多个用户线程对应同一个内核线程:

 第二种是一对一的关系,也就是一个用户线程对应一个内核线程:

 第三种是多对多的关系,也就是多个用户线程对应到多个内核线程:

 用户线程如何理解?存在什么优势和缺陷?

用户线程是基于用户态的线程管理库来实现的,那么线程控制块(Thread Control Block, TCB)也是在库里面来实现的,对于操作系统而言是看不到这个TCB的,内核无法感知用户级线程的存在,它只能看到整个进程的PCB 。

所以,用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等

用户级线程的模型,也就类似前面提到的多对一的关系,即多个用户线程对应同一个内核线程,如下图所示:

 用户线程的优点:

  • 每个进程都需要有它私有的线程控制块(TCB)列表,用来跟踪记录它各个线程状态信息(PC、栈指针、寄存器),TCB由用户级线程库函数来维护,可用于不支持线程技术的操作系统;
  • 用户线程的切换也是由线程库函数完成的,无需用户态和内核态的切换,所以速度特别快;

用户线程的缺点:

  • 由于操作系统不参与线程的调度,如果一个线程发起了系统调用而阻塞,那进程所包含的用户线程都不能执行了,无法做到真正意义上的并发
  • 当一个线程开始运行后,除非它主动交出CPU的使用权,否则它所在的进程当中的其他线程无法运行,因为用户态的线程没法打断当前运行中的线程,它没有这个特权,只有操作系统才有,但是用户线程不是由操作系统管理的
  • 内核资源的分配是根据进程分配的,用户级线程所在的进程可以竞争系统的资源,而每个用户线程只能竞争该进程内部的资源。对于一个进程,可能有成千上万个用户级线程,但是它们对系统的资源没有影响。

内核线程如何理解?存在什么优势和缺陷?

内核线程是由操作系统管理的,线程对应的TCB自然放在操作系统里,这样线程的创建、终止和管理都是操作系统负责

  • 内核级线程可以在全系统内进行资源的竞争
  • 内核空间内为每一个内核支持线程设置了一个线程控制块(TCB),内核根据该控制块,感知线程的存在,并进行控制。

内核线程的模型,也就是类似前面提到的一对一的关系,即一个用户线程对应一个内核线程,如下图所示:

内核线程的优点:

  • 在一个进程当中,如果某个内核线程发起系统调用而被阻塞,并不会影响其他内核线程的运行
  • 分配给线程,多线程的进程获得更多的CPU运行时间

内核线程的缺点:

  • 在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息,如PCB和TCB
  • 线程的创建、终止和切换都是通过系统调用的方式来进行,因此对于系统来说,系统开销比较大

 轻量级进程如何理解?

轻量级进程(Light-weight process, LWP)是内核支持的用户线程,一个进程可有一个或多个LWP,每个LWP是跟内核线程一对一映射的,也就是LWP都是由一个内核线程支持的,而且LWP是由内核管理并像普通进程一样被调度

在大多数系统中,LWP与普通进程的区别在于它只有一个最小的执行上下文和调度程序所需的统计信息。一般来说,一个进程代表程序的一个实例,而LWP代表程序的执行线程,因为一个执行线程不像进程那样需要那么多的状态信息,所以LWP也不带有这样的信息。

在LWP之上也是可以使用用户线程的,那么LWP与用户线程的对应关系就有三种:

  •  1 : 1 ,即一个LWP对应一个用户线程
  •  N : 1,即一个LWP对应多个用户线程
  •  M : N,即多个LWP对应多个用户线程

  1 : 1 模式

一个线程对应到一个LWP再对应到一个内核线程,如图的进程 4 ,属于此模型

  • 优点:实现并行,当一个LWP阻塞,不会影响其他LWP
  • 缺点:每一个用户线程,就产生一个内核线程,创建线程的开销较大。

 N : 1 模式

多个用户线程对应一个LWP再对应一个内核线程,如上图的进程 2 ,线程管理是在用户空间完成的,此模式中用户的线程对操作系统不可见

  • 优点:用户线程要开几个都没问题,且上下文切换发生在用户空间,切换的效率较高
  • 缺点:一个用户线程如果阻塞了,则整个进程都将会阻塞,另外在多核CPU中,没办法充分利用CPU

 M : N 模式

该模式提供了两级控制,首先多个用户线程对应多个LWP,LWP再 一一对应到内核线程,如上图的进程 3 。

  • 优点:综合了前两种的优点,大部分的线程上下文发生在用户空间,且多个线程又可以充分利用多核CPU资源

组合模式

如上图的进程 5,此进程结合 1:1 模型和 M:N 模型。开发人员可以针对不同的应用特点调节内核线程的数目来达到物理并行性和逻辑并行性的最佳方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/840880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习笔记:李宏毅ChatGPT课程1:刨析ChatGPT

ChatGPT——Chat Generative Pre-trained Transformer 1 文字接龙 每次输出一个概率分布,根据概率sample一个答案 ——>因为是根据概率采样,所以ChatGPT每次的答案是不一样的(把生成式学习拆分成多个分类问题)将生成的答案加到…

【Linux】总结1-命令工具

文章目录 基础指令shell命令以及运行原理Linux权限粘滞位工具 基础指令 ls、pwd、touch、mkdir、netstat、cp、mv、cd、tar、zip、unzip、grep、pstack、ps、rm、cat、more、less、head、tail、find、ulimit -a、clear、whoami、man touch:创建文件,也包…

怎么合并多个视频?简单视频合并方法分享

合并多个视频可以将它们组合成一个更长的视频,这对于需要播放多个短视频的情况非常有用。此外,合并视频还可以使视频编辑过程更加高效,因为不必将多个独立的视频文件分别处理。最后,合并视频可以减少文件数量,从而使整…

移动开发最佳实践:为 Android 和 iOS 构建成功应用的策略

您可以将本文作为指南,确保您的应用程序符合可行的最重要标准。请注意,这份清单远非详尽无遗;您可以加以利用,并添加一些自己的见解。 了解您的目标受众 要制作一个成功的应用程序,你需要了解你是为谁制作的。从创建…

Vue2 第二十一节 Vue UI组件库

移动端常用UI组件 1. Vant https://youzan.github.io/vant 2. Cube UI https://didi.github.io/cube-ui 3. Mint UI http://mint-ui.github.io PC端常用UI组件 1. Element UI https://element.eleme.cn 2. IView UI https://www.iviewui.com 一. Element UI 的引入和使…

cordova 12 编译失败Could not find method compile() for arguments [com....]

问题: Could not find method compile() for arguments [com.tencent.mm.opensdk:wechat-sdk-android-with-mta:] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. 问题原因: 在Cordova项目中&…

Qt之C++

Qt之C 类的定义 C语言的灵魂是指针 C的灵魂是类,类可以看出C语言结构体的升级版,类的成员可以是变量,也可是函数。 class Box { public://确定类成员的访问属性double length;//长double breadth;//宽度double heigth;//高度 };定义对象 …

mysql-数据库-创建列表

一.创建列表 1..首先,进入mysql数据库 -->mysql -uroot -p 2. 其次,mysql默认的数据库类型为mydb,这时候,就得查看现在使用的类型 mysql> select database(); 3. 如果创建的类型不同,则使用create database …

tensorboard无法显示数据的几个原因与解决方案【已解决】

本博客记录本人在学习tensorboard时关于浏览器无法显示数据问题的解决方案。该问题也算是折磨本人长达3个小时,我也相信有不少人为此感到苦恼,希望本文能给你提供某些帮助。 1.确保电脑与logs路径名称为英文 首先需要确保电脑名称为英文,否则…

SpringCloud(30):Nacos快速入门

1 安装Nacos Server 1.1 预备环境准备 Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用: 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux…

【计算机网络】12、frp 内网穿透

文章目录 一、服务端设置二、客户端设置 frp :A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet。是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,且…

力扣 -- 139. 单词拆分

一、题目 题目链接:139. 单词拆分 - 力扣(LeetCode) 二、解题步骤 下面是用动态规划的思想解决这道题的过程,相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码 class Solution { public:bool wordBreak(str…

学生管理系统(升级版)

import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class Demo_学生管理系统 {public static void main(String[] args) {ArrayList<User> list new ArrayList<>();Scanner sc new Scanner(System.in);while (true) {Syste…

Transformer1.0-预热

一.Encoder encoder:译为编码器&#xff0c;负责将输入序列压缩成指定长度的向量&#xff0c;这个向量就可以堪称是这个序列的语义。然后可进行编码或特征提取等操作 在transformer中encoder由6个相同的层组成&#xff0c;每个层包含 Multi-Head Self-AttentionPosition-Wise …

SEO 链接建设:初学者指南 2023

链接在互联网上扮演着一种宝贵的角色&#xff0c;就像货币一样重要。当其他网页纷纷指向某个网页时&#xff0c;这个网页就会被视为很有"权威"&#xff0c;在搜索引擎&#xff08;比如谷歌&#xff09;中获得更高的排名。相反地&#xff0c;如果一个网页没有别的网页…

linuxARM裸机学习笔记(6)----UART串口通信和串口格式化函数移植实验

UART串口通信 协议介绍&#xff1a;串口通信协议_ft232和ch340是串口的哪种协议_夜路难行々的博客-CSDN博客 I.MX6U UART UART时钟源选择的是pll3_80m&#xff0c;然后在(bit5:0)设置分频值&#xff0c;设置为1分频 ADBR(bit14) &#xff1a;自动波特率检测使能位&#xff0c…

个人信息保护合规审计管理办法的发展方向

8月3日&#xff0c;为指导、规范个人信息保护合规审计活动&#xff0c;中央网信办就《个人信息保护合规审计管理办法》及配套的《个人信息保护合规审计参考要点》公开征求意见 个人信息保护合规审计参考要点 第一条 本要点依据《中华人民共和国个人信息保护法》等法律、行政法…

基于Spring Boot的在线视频教育培训网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的在线视频教育培训网站设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java sp…

zabbix触发器标签提取监控项子字符串实现对应告警恢复

0 实验环境 zabbix 6.0 1 监控项 1.1 监控项设置 通过zabbix agent自定义监控项&#xff0c;读取某文件内容模拟日志/trap告警&#xff0c;测试获取触发器标签中提取子字符串功能&#xff0c;以及相同标签的触发器自动恢复功能。 1.2 手工运行 手动触发之后&#xff0c;模…

嵌入式开发学习(STC51-17-DAC数模转换)

内容 使DAC(PWM)模块上的指示灯DA1呈呼吸灯效果&#xff0c;由暗变亮再由亮变暗&#xff1b; DAC介绍 简介 DAC&#xff08;Digital to analog converter&#xff09;即数字模拟转换器&#xff0c;它可以将数字信号转换为模拟信号&#xff0c;它的功能与ADC相反&#xff1b…