【lesson52】 线程概念

文章目录

  • 线程学习前的了解知识
  • 理解线程

线程学习前的了解知识

线程在进程内部执行,是OS调度的基本单位
OS可以做到让进程对进程地址空间进行资源的细粒度划分
在这里插入图片描述
比如malloc一块内存空间,我们拿到的一般都是起始位置,但是最终位置我们一般都不知道。
进程内部有struct vm_area_struct结构体。
在这里插入图片描述
vm管理虚拟地址空间的起始地址和末尾地址。而struct vm_area_struct也要用链表结构管理起来。
在这里插入图片描述
我们知道虚拟地址的映射是通过页表的,那么如何从虚拟内存映射到物理内存
在这里插入图片描述
1.exe就是一个文件
2.我们的可执行程序本来就是按照地址空间方式进行编译的。
3.可执行程序,其实按照区域也已经划分了以4KB为单位。

在这里插入图片描述
物理内存有4GB,划分为4KB的个数
在这里插入图片描述

OS要不要管理100W+个4KB空间呢?当然要,先描述再组织

在这里插入图片描述
我们如何判断某4KB空间有没有被使用?我们只要看flag标记位即可。

物理内存被划分为4KB,而I/O的基本单位也是4KB
页表映射过程:
首先虚拟内存是映射到,磁盘的可执行程序的位置。
在这里插入图片描述
而可执行程序被加载到物理内存后,就有了物理内存的地址。
然后断开磁盘的地址,将物理内存的地址填入映射表中。
在这里插入图片描述
这个过程也叫缺页中断这个过程用户是零感知的,也就是对用户透明。

我们知道页表是映射地址的,那么页表如何映射?
假设在32的平台下,虚拟内存有232次方个地址。我们简单计算一下页表的大小。
在这里插入图片描述
我们看到一行就需要9字节,而有232行,那么所需的空间都超了4GB,而页表也是属于物理内存的所以根本不可能存的下。
那么OS是怎么做的呢?
OS将页表分为一级页表二级页表,一个地址有32个比特位,一级页表存前10个bit位二级页表存中间10个bit位最后12页bit位表示页内偏移,212刚好是4KB
在这里插入图片描述

理解线程

什么是线程

  • 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”
  • 一切进程至少都有一个执行线程
  • 线程在进程内部运行,本质是在进程地址空间内运行
  • 在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化
  • 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

通过一定的技术手段,将当前进程的“资源”,以一定的方式划分给不同的task_struct。
在这里插入图片描述
多个进程(task_struct)指向同一个mm_struct—>这里每一个task_struct,都可以称之为线程---->Linux特有的实现线程的方案。
线程是在进程内部执行的(线程在进程放入地址空间内运行),是OS调度的基本单位。(CPU其实并不关心,执行流是进程还是线程,只关心task_struct
在这里插入图片描述
所以什么是进程呢?
1.从资源角度
用户视角:
内核数据结构+该进程对应的代码和数据
内核视角:
进程:承担分配系统资源的基本实体。
进程是直接向OS要资源的,而线程是向进程要资源的。

2.如何理解曾今我们所写的代码?
以前:内部只有一个执行流的进程
现在:内部具有多个执行流的进程---->task_struct就是进程内部的一个执行流

在CPU视角:CPU不怎么关系当前是进程还是线程的概念,只认task_struct。—>和之前的概念也不冲突---->CPU调度的基本单位“线程”

在Linux下 进程PCB <= 其它OS内的 进程PCB!----->所以Linux下的进程统一称为轻量级进程

所以Linux没有真正意义上的线程结构,Linux是用进程PCB(task_struct)模拟的线程!---->Linux并不能直接给我们提供线程相关的接口,只能提供轻量级进程接口---->但是使用者要使用线程的话还要理解什么是轻量级进程,很麻烦---->所以Linux也考虑了使用者的难处,所以在用户层实现了一套用户层多线程方案,以库的方案提供给用户进行使用。
Linux的pthread线程库是Linux提供的原生线程库

线程的优点

  1. 创建一个新线程的代价要比创建一个新进程小得多
  2. 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多 线程占用的资源要比进程少很多
  3. 能充分利用多处理器的可并行数量
  4. 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
  5. 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  6. I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

线程的缺点

  • 性能损失
    一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的
    同步和调度开销,而可用的资源不变。

  • 健壮性降低
    编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。

  • 缺乏访问控制
    进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。

  • 编程难度提高
    编写与调试一个多线程程序比单线程程序困难得多

线程异常

  • 单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃
  • 线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出

线程用途

  • 合理的使用多线程,能提高CPU密集型程序的执行效率
  • 合理的使用多线程,能提高IO密集型程序的用户体验(如生活中我们一边写代码一边下载开发工具,就是多线程运行的一种表现)

Linux进程VS线程

  • 进程和线程
    进程是资源分配的基本单位
    线程是调度的基本单位
    线程共享进程数据,但也拥有自己的一部分数据:
    – 线程ID
    – 一组寄存器
    – 栈
    – errno
    – 信号屏蔽字
    – 调度优先级

进程的多个线程共享 同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:

  • 文件描述符表
  • 每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)
  • 当前工作目录
  • 用户id和组id

在这里插入图片描述

见一见线程
在这里插入图片描述
在这里插入图片描述
参数解释:
thread:输出型参数返回线程id
attr:
在这里插入图片描述
start_routine:函数指针,线程要执行的回调函数
arg:回调函数的参数
代码:
在这里插入图片描述

运行结果:
在这里插入图片描述
我们看到确实2个线程是同一个pid
那么我们如何查看线程呢?
打开连个窗口,一个窗口运行代码,一个窗口观察线程
窗口2:运行代码
在这里插入图片描述
窗口一查看进程和线程
先查看进程:
在这里插入图片描述
看到确实只有一个进程
再查看线程:
在这里插入图片描述
我们看到确实有两个线程。

ps -aL: 查看轻量级进程
LWP:轻量级进程ID
CPU调度时看的是LWP.

kill -9 进程id,进程被kill线程也被kill
演示:
在这里插入图片描述

创建多个线程:
代码:

#include <iostream>
#include <pthread.h>
#include <unistd.h>void *threadRoutine(void *arg)
{char* name = (char*)arg;while (true){std::cout << name << " pid:" << getpid() << "\n" << std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid[5];char name[64];for (int i = 0; i < 5; i++){snprintf(name, sizeof(name), "%s %d", "thread", i + 1);pthread_create(tid + i, nullptr, threadRoutine, (void*)name);sleep(1);}while (true){std::cout << "main thread pid:" << getpid() << std::endl;sleep(3);}return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

CPU线程进行切换的成本低,为什么?
地址空间和页表不需要切换,因为都共用一个进程的地址空间和页表,CPU内部有L1~L3寄存器cache,对内存的代码和数据根据局部性原理,预读进CPU内部!

如果进程切换,cache就立即失效的话,新过来的进程只能重新缓存

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kali系统概述、nmap扫描应用、john破解密码、抓包概述、以太网帧结构、抓包应用、wireshark应用、nginx安全加固、Linux系统加固

目录 kali nmap扫描 使用john破解密码 抓包 封装与解封装 网络层数据包结构 TCP头部结构​编辑 UDP头部结构 实施抓包 安全加固 nginx安全 防止缓冲区溢出 Linux加固 kali 实际上它就是一个预安装了很多安全工具的Debian Linux [rootmyhost ~]# kali resetkali …

一、Docker/安装包部署ClickHouse

Docker/安装包部署ClickHouse 一、docker部署1.安装Docker2.拉取ClickHouse镜像2.1 选择拉取版本2.2 拉取镜像 3.启动ClickHouse3.1 确定好挂载目录3.2 测试环境3.3 生产环境3.1.1 获取配置文件3.1.2 配置文件中添加用户3.1.3 启动容器 4.使用DBeaver连接 二、安装包安装1.准备…

数据结构——线性表

逻辑结构——线性表 1.线性表的定义&#xff08;逻辑结构&#xff09; 要点&#xff1a; 相同数据类型有限序列 几个概念&#xff1a; 是线性表中的“第i个”元素线性表中的位序 是表头元素&#xff1b;是表尾元素。 除第一个元素外&#xff0c;每个元素有且仅有一个直接前驱&…

用C语言列出Linux或Unix上的网络适配器

上代码&#xff1a; 1. #include <sys/socket.h> 2. #include <stdio.h> 3. 4. #include <netdb.h> 5. #include <ifaddrs.h> 6. 7. int main() { 8. struct ifaddrs *addresses; 9. if(getifaddrs(&addresses) -1) { 10. printf("…

股票K线简介

股票K线&#xff08;K-Line&#xff09;是用于表示股票价格走势的图形&#xff0c;主要由四个关键价格点组成&#xff1a;开盘价、收盘价、最高价和最低价。K线图广泛应用于股票市场技术分析中&#xff0c;它提供了丰富的信息&#xff0c;帮助分析师和投资者理解市场的行情走势…

微信小程序(四十四)鉴权组件插槽-登入检测

注释很详细&#xff0c;直接上代码 新增内容&#xff1a; 1.鉴权组件插槽的用法 2.登入检测示范 源码&#xff1a; app.json {"usingComponents": {"auth":"/components/auth/auth"} }app.js App({globalData:{//定义全局变量isLoad:false} })…

数据分析基础之《pandas(7)—高级处理2》

四、合并 如果数据由多张表组成&#xff0c;那么有时候需要将不同的内容合并在一起分析 1、先回忆下numpy中如何合并 水平拼接 np.hstack() 竖直拼接 np.vstack() 两个都能实现 np.concatenate((a, b), axis) 2、pd.concat([data1, data2], axis1) 按照行或者列…

【JAVA WEB】JavaScript--函数 作用域 对象

目录 函数 语法格式 示例 定义没有参数列表&#xff0c;也没有返回值的一个函数 定义一个有参数列表 &#xff0c;有返回值的函数 关于参数个数 函数表达式 作用域 作用域链 对象 基本概念 创建对象 1.使用 字面量 创建对象 2.使用new Object()创建对象 3.使…

七、热身仪式(Warm-Up Rituals)

5.Warm Up Rituals 五、热身仪式 A warm up ritual is your per flight checklist you go through before you start focusing for a big session.It may be checking that you have water, that you don’t need to use the bathroom, that your phone is turned off or you’…

docker 3.1 镜像

docker 3.1 镜像命令 拉取镜像 docker pull debian #从 Docker Hub 拉取名为 debian 的镜像docker pull hello-world #从 Docker Hub 拉入名为 hello-world 的镜像‍ 运行镜像/容器 docker run hello-world ‍ 查看本地所有的镜像 docker images​​ 容器生成镜像…

STM32 cubemx配置DMA+空闲中断接收不定长数据

文章目录 前言一、串口空闲中断二、DMA空闲中断接收不定长数据实现思路三、STM32Cubemx配置DMA空闲中断接收不定长数据四、代码编写总结 前言 本篇文章给大家讲解一下DMA串口空闲中断接收串口不定长数据&#xff0c;之前我们也是讲解过串口接收不定长数据的&#xff0c;那么本…

2024.2.14

二维数组实现杨辉三角形 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) {int n;scanf("%d",&n);int a[n][n];for(int i0;i<n;i){for(int j0;j<i;j){if(j0||ij){ a[i][j]1;}else{a[i][j]a[i-1][j]a[i-1][j-…

Netty应用(九) 之 编解码器概念 Netty常见的编解码器

目录 22.编解码器 22.1 编解码的概念 22.2 netty中的编解码 22.3 序列化 23.编解码器在使用过程中的两部分核心内容 23.1 序列化协议&#xff08;编码格式&#xff09;&#xff08;传输数据的格式&#xff09; 23.1.1 Java默认的序列化与反序列化 23.1.2 XML的序列化与反…

函数求导法则【高数笔记】

【分类】 1. 四则运算求导 2. 复合运算求导 3. 整体思想求导 #整体思想求导本质是运用复合运算求导&#xff0c;只不过是对复合运算求导的一种精炼 #无论是具体函数还是抽象函数求导&#xff0c;方法是一致的 【四则运算求导】 加&#xff0c;减&#xff0c;乘&#xff0c;除&a…

代码随想录算法训练营第四十九天(动态规划篇)| 474. 一和零, 完全背包理论基础

474. 一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/submissions/501607337/ 思路 之前的背包问题中&#xff0c;我们对背包的限制是容量&#xff0c;即每个背包装的物品的重量和不超过给定容量&#xff0c;这道题的限制是0和1的个数&#xff0…

寒假 day13

1.请编程实现二维数组的杨慧三角 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int n,i,j;printf("please enter n:");scanf("%d",&n);int arr[n][n];for(i0;i<n;i){for(j0;j<i;j){if(j0 || ij…

【51单片机】LCD1602(江科大)

1.LCD1602介绍 LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符 显示容量:162个字符,每个字符为5*7点阵 2.引脚及应用电路 3.内部结构框图 屏幕: 字模库:类似于数码管的数…

HTML 超文本标记语言

超文本标记语言 HTML 在一个客户程序主窗口上显示出的万维网文档称为页面 (page)。 页面制作的标准语言&#xff1a;HTML。 超文本标记语言 HTML (HyperText Markup Language) 是一种制作万维网页面的标准语言&#xff0c;它消除了不同计算机之间信息交流的障碍&#xff0c…

“掌握温度,感知湿度,一触即知!”DHT11温湿度传感器,为您的生活增添一份关怀与精准。#非标协议【下】

“掌握温度&#xff0c;感知湿度&#xff0c;一触即知&#xff01;”DHT11温湿度传感器&#xff0c;为您的生活增添一份关怀与精准。#非标协议【下】 前言预备知识1.DHT11温湿度传感器初识1.1产品概述1.2与51单片机接线1.3数据传送逻辑和数据格式 2.发送时序检测DHT11温湿度传感…

2.14 指针练习

1、选择题 1.1、若有下面的变量定义&#xff0c;以下语句中合法的是&#xff08; A &#xff09;。 int i&#xff0c;a[10]&#xff0c;*p&#xff1b; A&#xff09; pa2; B&#xff09; pa[5]; C&#xff09; pa[2]2; D&#xff09; p&(i2); 解析&am…