线程 - 线程优缺点、线程自有和共享的数据、多线程使用公共空间、线程分离、线程库对线程的管理

news2025/2/23 16:43:06

文章目录

  • 一、线程的优点
    • 1. 创建的代价
    • 2. 切换的代价
      • 缓存和进程/线程切换
    • 3. 占用的资源
    • 4. 效率
  • 二、线程的缺点
    • 1. 性能损失
    • 2. 健壮性降低
    • 3. 缺乏访问控制
    • 4. 编程难度高
  • 三、线程分离
    • 1. 线程分离
    • 2. pthread_detach ()
      • ① 函数细节
      • ② 函数使用
  • 四、线程自有和共享的数据
    • 1. 线程自有的数据
    • 2. 线程共享的资源
  • 五、多个线程使用公共空间
    • 1. 不要把公共空间传给多个线程
      • 1.1 问题
      • 1. 2 解决
    • 2. 线程的传参和返回值,可以是各种对象
  • 六、C++11 中的线程
    • 1. C++11 的多线程
    • 2. thread 类及使用
  • 七、线程库对线程的管理
    • 1. 线程的管理由谁来做?
    • 2. 线程管理的细节
      • ① 线程库首先要映射到当前进程的地址空间中
      • ② 进程地址空间中的动态线程库
      • ③ 整个系统的所有的线程都在这一个库中管理着
    • 3. 执行流怎么找到栈的?
  • 八、线程的封装
    • 1. Pthread.hpp
    • 2. test.cc

一、线程的优点

1. 创建的代价

创建一个新线程的代价要比创建一个新进程小的多。


创建线程只需要创建一个新的 PCB,然后将曾经进程的资源指派给线程即可;而进程创建的时空成本是较高的,有各种数据结构的创建,数据的加载。

2. 切换的代价

与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多。


缓存和进程/线程切换

  • CPU内,每次读取当前进程的代码和数据时,都需要经过虚拟到物理的转换,然后得到内存中的数据放到 CPU 中做处理,如果这样,那 CPU 读取任何一条指令,都要访问内存,为了提高运行效率,CPU 中存在一种硬件 cache(高速缓冲存储器),在 CPU 进行虚拟到物理的寻址时,本来是找到一行代码,较大概率会执行下一行(当然也可能会跳转到别处),所以会将周边数据全读到 CPU 内部缓存起来,所以,之后 CPU 再访问代码数据时,不用再去读取内存了,而是从 cache 中再读取,大大提高 CPU 寻址的效率。
    在这里插入图片描述
  • 进程切换和线程切换:
    • 进程切换:
      在这里插入图片描述
      之前缓存的数据,就全都没有了,会重新加载新进程的数据

    • 线程切换:
      在这里插入图片描述
      cache 中的数据在概率上依旧能用,不用重新清空和重新加载。

所以这才是线程成本低的主要原因。

3. 占用的资源

线程占用的资源要比进程少很多。


进程要占用多执行流,地址空间,页表,代码数据;而线程占用的都是一份的。

4. 效率

  • 计算密集型应用:
    排序、查找、加密、解密、压缩等动作都以计算为主,是计算密集型应用,主要应用的 CPU 的资源。
  • I/O 密集型应用:
    下载、上传、拷贝等就是 I/O 密集型应用。

应用要不就是计算密集型,要不就是 I/O 密集型,要不就是两者都是。

  • 对于计算密集型应用:
    • 为了能在多处理器系统上运行,将计算分解到多个线程中实现。一个线程处理一部分,效率会高。
    • 当然也不是创建的线程越多越好,因为会有切换的成本,切换太多,说不定效率还不如一个进程从头算到尾。
    • 所以,对于计算密集型,一般是 CPU 有多少个核就创建几个。
      可以通过 lscpu 查看一下核数:在这里插入图片描述
  • 对于I/O 密集型应用:
    • 可以多创建进程,因为 I/O 过程大部分都在等,一个进程等 10G的数据,和 10 个线程每个等 1G 的数据,效率不一样。

二、线程的缺点

1. 性能损失

多线程切换有成本,像上面的计算密集型应用,线程过多可能会有较大的性能损失(增加了额外的同步和调度开销,而可用资源不变)。

2. 健壮性降低

一个线程出问题,整个进程就挂掉了(这一点,线程 - 线程退出 中有讲到)。
在一个多线程程序里,因共享了不该共享的变量而造成不良影响的可能性很大。

3. 缺乏访问控制

线程间共享资源,对于共享资源,大家都可以任意时间访问,可能会有同时访问同一量的情况,可能会出错。

4. 编程难度高

编写与调试一个多线程程序比单线程程序要困难很多,往往需要全面深入的考虑以保证程序的健壮性。

三、线程分离

1. 线程分离

线程默认是 joinable(可联接) 的,如果主线程不关心新线程的执行信息,可以将新线程设置为分离状态。
当线程处于分离状态后,退出时会自动释放线程资源。
在这里插入图片描述

  • 分离和等待:
    线程被分离后,就不能被 pthread_join() 了,调用这个函数,函数就会返回一个错误码。
  • 分离状态:
    ‘分离’仅仅是一种状态,一种不用主线程等的状态,而不是真正分离了。在这种状态下,线程出异常了,进程会受影响退出;主线程执行完了,进程退出,线程也会退出。

不管是分离还是等待,我们都希望主线程是最后退出的,所以分离的一个场景,就是主进程根本就不退出。
大部分程序都是一直在运行的,称为常驻进程。

2. pthread_detach ()

① 函数细节

在这里插入图片描述

  • thread 参数:要分离的线程的ID
  • 返回值:成功返回 0 ,失败返回错误码

② 函数使用

  • 主线程分离新线程:
#include <pthread.h>
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>

using std::cout;
using std::endl;

void *thfunc(void *arg)
{
   
    while (1)
    {
   
        sleep(1);
        cout << "new" << endl;
    }
    return nullptr;
}
int main()
{
   

    pthread_t rid;
    pthread_create(&rid, nullptr, thfunc, nullptr);

    pthread_detach(rid);

    sleep(3);
    cout << "man" << endl;

    return 0;
}

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

  • 新线程自己分离自己:
void *thfunc(void *arg)
{
   
    pthread_detach(pthread_self());
    while (1)
    {
   
        sleep(1);
        cout << "new" << endl;
    }
    return nullptr;
}
int main()
{
   
    pthread_t rid;
    pthread_create(&rid, nullptr, thfunc, nullptr);

    sleep(3);
    cout << "man" << endl;

    return 0;
}

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

  • 在线程分离后,再通过 pthread_join() 等待线程会等待失败,函数会返回一个错误码:
    在这里插入图片描述

四、线程自有和共享的数据

进程是资源分配的基本单位,线程是调度的基本单位。进程强调独立,线程强调共享。所以我们来看一下线程自有的和共享的部分。

1. 线程自有的数据

  • 线程 ID: 是用户级别的,内核级的不使用线程 ID,使用的是线程的 LWD
  • 硬件上下文: 每个线程都是被单独调度的执行流,所以要有自己的上下文数据,存放在一组寄存器中。
  • 独立栈结构: 线程本质是在执行自己的函数,每个函数内都可以定义各种临时变量,临时变量都是存放在栈上的。每个线程都有独立的用户栈,不敢让它们一起用一块栈空间。

除了上面几个较为重要的,还有 errno、信号屏蔽字、调度优先级等。

2. 线程共享的资源

  • 地址空间
  • 文件描述符表:因为文件描述符表表示的是进程和打开文件的关系,而不是线程。
  • 每种信号共享的处理方式:这就是为什么一个线程出异常,整个进程就崩掉了。
  • 当前工作目录:进程在哪里,线程就在哪里。
  • 用户 id 和组 id

五、多个线程使用公共空间

1. 不要把公共空间传给多个线程

我们来看下面这段代码:
我们想一次性创建 6 个线程,然后每一个线程都在自己的线程函数中打印一下自己的线程名字(从 16 号)。

#include <pthread.h>
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>

using std::cout;
using std::endl;

const int threadsnum =

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

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

相关文章

[数据集][目标检测]无人机飞鸟检测数据集VOC+YOLO格式6647张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6647 标注数量(xml文件个数)&#xff1a;6647 标注数量(txt文件个数)&#xff1a;6647 标注…

酒店布草洗涤-酒店分层管理编程实现--———未来之窗行业应用跨平台架构

一、添加楼层代码 未来之窗_人工智能_传送阵(添加楼层,客户信息,300,200) CyberWin_Dialog.layer(未来之窗传送,{type:"url",title:title,move:true,width:阵眼宽度"px",height:阵眼高度"px",id:未来之窗app_通用ID,mask:false,align:59,hidecl…

css 样式简单学习(一)

目录 1. css 介绍 1.1 css 样式 1.2 css代码风格 1.2.1 书写格式 1.2.2 样式大小写​编辑 1.2.3 空格规范 2. 基础选择器 2.1 选择器的作用​编辑 2.2 选择器的分类 2.3 基础选择器 2.3.1 标签选择器​编辑 2.3.2 类选择器​编辑 2.3.3 类选择器-多类名​编辑 2.…

Linux硬连接、软连接和复制的区别

‌硬连接、软连接和复制在Linux系统中的主要区别体现在以下三点&#xff1a; 文件链接的方式文件独立性文件系统的操作上。‌ 一、硬连接 1. 硬连接是通过ln命令创建的&#xff0c;它为文件创建别名&#xff0c;与源文件共享同一inode号码&#xff0c;因此硬连接和源文件实际…

松散绑定是什么?

概念 比如我的yml中写的last-name,这个和lastName是一样的&#xff0c;-后面跟着的字母默认是大写的&#xff0c;这就是松散绑定 示例 类代码&#xff1a; public class Person {private String lastName;private Integer age;private Boolean happy;private Date birth;pr…

c++与cmake:完整的C++项目构建注意事项

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 最近常常使用cmake构建c项目有感,从创建项目到打包发布总结一下需要注意的事情. 项目组织方式 具体的项目组织方式因人而异,这里推荐一种,在src目录中创建模块目录,再在include目录中常见对应的同名目录包含头文件,…

【Binlog实战】:基于Spring监听Binlog日志

【Binlog实战】&#xff1a;基于Spring监听Binlog日志 binlog的三种模式 MySQL 的二进制日志&#xff08;binlog&#xff09;有三种不同的格式&#xff0c;通常被称为 binlog 模式。这三种模式分别是 Statement 模式、Row 模式和Mixed 模式。 Statement 模式&#xff1a; 在 …

Redis存储原理

前言 我们从redis服务谈起&#xff0c;redis是单reactor&#xff0c;命令在redis-server线程处理。还有若干读写IO线程负责IO操作&#xff08;redis6.0之后&#xff0c;Redis之pipeline与事务&#xff09;。此外还有一个内存池线程负责内存管理、一个后台文件线程负责大文件的关…

信息安全数学基础(17)Wilson定理

前言 Wilson定理&#xff08;Wilsons Theorem&#xff09;是数论中的一个基本定理&#xff0c;它揭示了素数与其阶乘之间的一个重要关系。 一、表述 对于任意素数p&#xff0c;有(p−1)!≡−1(modp)&#xff0c;其中(p−1)!表示p−1的阶乘&#xff0c;即123⋯(p−1)。 这个定理…

C++STL~~priority_queue

文章目录 容器适配器一、priority_queue的概念二、priority_queue的使用三、priority_queue的练习四、仿函数五、总结 容器适配器 什么是适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff0c;该种模式是将…

python画图|3D bar进阶探索

前述学习过程只能怪&#xff0c;已经探究了3D直方图的基础教程&#xff0c;详见下述链接&#xff1a; python画图|3D直方图基础教程-CSDN博客 实际上&#xff0c;基础文章直接进入了堆叠教程&#xff0c;相对来说基础的程度不够&#xff0c;因此有必要再次探索。 【1】官网教…

spug项目实现代码本地启动步骤

一、spug代码仓库地址: spug: 开源运维平台&#xff1a;面向中小型企业设计的无 Agent的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件在线上传下载、应用发布、任务计划、配置中心、监控、报警等一系列功能。 - Gitee.com 注意&#xff1a;如…

【制作100个unity游戏之32】unity开发属于自己的一个2d/3d桌面宠物,可以实时计算已经获取的工资

最终效果 文章目录 最终效果一、实现Windows消息弹窗二、将窗口扩展到工作区三、穿透能点击到其他区域四、模型交互1、我们可以新增ObjectDrag 代码控制人物拖拖动2、实现模型交互五、最终代码六、其他七、游玩地址使用Live2D实现桌宠七、源码参考完结一、实现Windows消息弹窗 …

jetson nano开发板安装todesk远程乌班图aarch版本

打开todesk官网&#xff0c;并打开Linux系统的一栏&#xff1a;ToDesk远程桌面软件-免费安全流畅的远程连接电脑手机 我这里选择deb安装包&#xff0c;然后安装依赖 sudo apt-get install libappindicator3-1 由于我下载上传到了根目录&#xff0c;所以直接在终端运行安装命令…

Golang | Leetcode Golang题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; func addStrings(num1 string, num2 string) string {add : 0ans : ""for i, j : len(num1) - 1, len(num2) - 1; i > 0 || j > 0 || add ! 0; i, j i - 1, j - 1 {var x, y intif i > 0 {x int(num1[i] - 0)}if j &g…

nonlocal本质讲解(前篇)——从滤波到Nonlocal均值滤波

线性滤波 → \rightarrow →高斯滤波 → \rightarrow →高斯滤波 → \rightarrow →双边滤波 → \rightarrow →Nonlocal均值滤波 平均 高斯 双边 Nonlocal 目录 线性滤波高斯滤波双边滤波Nonlocal均值滤波 滤波最初是频域的概念&#xff0c;由于频域乘积对应空域卷积&am…

Qwen2-VL环境搭建推理测试

引子 2024年8月30号&#xff0c;阿里推出Qwen2-VL&#xff0c;开源了2B/7B模型&#xff0c;处理任意分辨率图像无需分割成块。之前写了一篇Qwen-VL的博客&#xff0c;感兴趣的童鞋请移步&#xff08;Qwen-VL环境搭建&推理测试-CSDN博客&#xff09;&#xff0c;这么小的模…

Spring Cloud Alibaba-(1)搭建项目环境

1.Spring Cloud Alibaba&#xff08;官网&#xff1a;https://sca.aliyun.com/&#xff09; Spring Cloud Alibaba 是阿里巴巴结合自身丰富的微服务实践而推出的微服务开发的一站式解决方案&#xff0c;是 Spring Cloud 第二代实现的主要组成部分。吸收了 Spring Cloud Netflix…

一键文本提示实现图像对象高质量剪切与透明背景生成

按照提示词裁剪 按照边框裁剪 要实现您描述的功能,即通过一个文本提示就能自动从图片中切割出指定的对象并生成一个带有透明背景的新图像,这需要一个结合了先进的计算机视觉技术和自然语言处理能力的系统。这样的系统可以理解输入的文本指令,并将其转化为对图像内容的精确分…

深入探究HTTP网络协议栈:互联网通信的基石

在我们日常使用互联网的过程中&#xff0c;HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;扮演着至关重要的角色。无论是浏览网页、下载文件&#xff0c;还是进行在线购物&#xff0c;HTTP协议都在背后默默地支持着这些操作。今天&#x…