【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.hqwc.cn/news/468109.html

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

相关文章

【JavaEE进阶】 图书管理系统开发日记——陆

文章目录 &#x1f38b;前言&#x1f343;删除图书&#x1f6a9;约定前后端交互接口&#x1f6a9;完善前端代码&#x1f6a9;接口测试 &#x1f38d;批量删除&#x1f6a9;约定前后端交互接口&#x1f6a9;实现后端服务器代码&#x1f388;控制层&#x1f388;业务层&#x1f3…

中科大计网学习记录笔记(十一):CDN

前言&#xff1a; 学习视频&#xff1a;中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版&#xff0c;James F.Kurose&#xff0c;Keith W.Ross&#xff09;》课程 该视频是B站非常著名的计网学习视频&#xff0c;但相信很多朋友和我一样在听完前面的部分发现信…

蓝牙BLE学习-GAP

1.概述 GAP层&#xff08;Generic access profile-通用访问配置文件&#xff09;。GAP是对LL层payload&#xff08;有效数据包&#xff09;如何进行解析的两种方式的一种&#xff0c;而且也是最简单的一种。GAP简单的对LL payload进行一些规范和定义&#xff0c;因此GAP能实现的…

【博云2023】乘龙一跃腾云海,侧目抬手摘星河

癸卯渐远&#xff0c;甲辰渐至&#xff0c;预示着被汗水浇灌的种子&#xff0c;必将顶开冻土&#xff0c;迎接阳光。 每逢春节&#xff0c;当亲友彼此问候&#xff0c;博云人总能自豪地说&#xff0c;我们认真地、努力地奋斗&#xff0c;让我们能自信地踏上新的征程。 我们的…

【使用Cpolar将Tomcat网页传输到公共互联网上】

文章目录 1.前言2.本地Tomcat网页搭建2.1 Tomcat安装2.2 配置环境变量2.3 环境配置2.4 Tomcat运行测试2.5 Cpolar安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#…

C++线程浅谈

本篇文章我们来介绍一下C 多进程 多线程的技术 1.为什要学习多线程 多进程 提高程序的性能&#xff1a;进程和线程可以使程序并发执行&#xff0c;从而充分利用计算机的多核处理器和资源&#xff0c;提高程序的执行效率和吞吐量。 实现复杂任务&#xff1a;通过将任务划分为多…

Windows搭建docker+k8s

安装Docker Desktop 从官网下载&#xff0c;然后直接安装即可&#xff0c;过程很简单&#xff0c;一直Next就行。 有一点需要注意就是要看好对应的版本&#xff0c;因为后边涉及到版本的问题。 https://www.docker.com/products/docker-desktop 安装完成&#xff0c;双击图…

Linux_动静态库

动态库 静态库 刚开始学编程时&#xff0c;需要下载一个环境&#xff08;vs2019&#xff09;&#xff0c;这个环境包括编译器和标准库&#xff0c;标准头文件。那么什么是库呢&#xff0c;库和头文件有什么关系呢&#xff1f; 头文件里面放的函数声明&#xff0c;库文件里面放…

Spring Boot3自定义异常及全局异常捕获

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 目的 主要步骤 定义自定义异常类 创建全局异常处理器 手动抛出自定义异常 前置条件 已经初始化好一个…

建立网站的主要步骤

建立网站的主要步骤 最近&#xff0c;我无意中发现了一个异常有用的资源&#xff0c;它提供了一种令人惊叹的机会&#xff0c;可以获取免费的域名和SSL证书。这个资源位于https://www.rainyun.com/z22_&#xff0c;我迫不及待地要与你分享这个宝贵的发现。 在这个数字时代&…

ARM:AI 的翅膀,还能飞多久?

ARM&#xff08;ARM.O&#xff09;于北京时间 2024 年 2 月 8 日上午的美股盘后发布了 2024 年第三财年报告&#xff08;截止 2023 年 12 月&#xff09;&#xff0c;要点如下&#xff1a; 1、整体业绩&#xff1a;收入再创新高。ARM 在 2024 财年第三季度&#xff08;即 23Q4…

第二篇【传奇开心果微博系列】Python微项目技术点案例示例:成语接龙游戏

传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目目标二、雏形示例代码三、扩展整体思路四、玩家输入示例代码五、成语判断示例代码六、回答判断示例代码七、电脑判断示例代码八、游戏结束示例代码九、界面优化示例代码十、扩展成语库示例代…