当前位置: 首页 > news >正文

《Linux从练气到飞升》No.25 Linux中多线程概念

🕺作者: 主页

我的专栏
C语言从0到1
探秘C++
数据结构从0到1
探秘Linux
菜鸟刷题集

😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!

文章目录

    • 前言
    • 线程的基本概念
      • Linux中的线程
      • Linux线程与进程区别
      • 进程和线程的关系
      • Linux线程和接口的认识
      • 线程的数据
        • 线程的私有数据
        • 线程的共有数据
      • 看看猪跑
    • 线程的优缺点(了解)
      • 线程的优点
      • 线程的缺点
        • 线程异常
    • 线程用途

前言

本篇主要介绍一下线程相关的知识~

线程的基本概念

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

理解:
一个进程对应着的线程应该>=1,它至少要含有一个线程才能维持进程的存在,所谓的更加轻量化指的是每个线程都享有进程内的一定的资源,并负责各自的任务,相对来说就更加精细化和轻量化,所以说在内核视角中线程是CPU调度的基本单位,承担进程资源的一部分基本实体。
毫无疑问,在操作系统中存在大量的进程,现在我们知道,一个进程对应着至少一个线程,那么可以推断在操作系统中会存在更多的线程,既如此操作系统为了管理它就会想办法将它们组织起来,之前将进程的时候讲过,操作系统管理的法则是“先描述,再组织”,进程是用一个叫PCB的结构体来描述的,线程是用一个叫TCB的结构体来描述的,在windows操作系统中就是这样管理线程的,不过在Linux中则使用了一种巧妙的方法来管理。

Linux中的线程

之前在进程部分我们讲过 进程 = 程序 + PCB + mm_struct + 页表和mmu + 物理地址,Linux在创造线程概念的时候并没有像上面我们所推断的一样创造TCB结构体来管理每一个线程 而是复用了进程的PCB结构体,如下图。
image.png
这些线程的task_struct和进程task_struct共享同一个进程地址空间,每个线程都会使用其中部分代码和数据,但是CPU并不管这些,它只管执行就好,这样的优点是操作系统只需要将“精力”专注于线程间的资源分配就好了。

Linux线程与进程区别

我们在创建进程的时候通常会为进程创建一个独立的程序地址空间来保证它的独立性而线程则恰恰相反它们只创建PCB共用一个进程地址空间。
但是同样的进程间为了通信或者是其他目的也会选择性的共用一块公共资源而线程为了保证自己能够正确运行也会有一些相对其他线程独立的资源。
主要区别如下:

  • 进程具有独立性 但是一部分资源是可以共享的(管道 ipc等)
  • 线程大部分资源是共享的 但是一部分资源是私有的 (PCB 栈 上下文等)

进程和线程的关系

如果我们把国家比作一个操作系统 那么国家中的每个家庭就是一个进程。每个家庭之间是相互独立的,不可能说今天另外一个家庭的人不经过你的同意就住进你家里。
但是家庭与家庭之间也需要通信,可能周末会邀请关系好的邻居上你家客厅做客。
家庭中的每个人就可以看作是线程,在这个家里大部分的资源是共享的,但是每个人也有自己的隐私,所以说一部分资源是私有的。

Linux线程和接口的认识

在Linux中线程是用进程模拟实现的,所以说Linux中不会给我们提供线程的操作接口 (这里解释下 其实Linux不是没有能力去提供这些操作接口 而是它想要保持一个相对自由的状态给用户) ,而是给我们提供了一个在同一个进程地址空间中创建PCB的方法 ,分配给资源指定的PCB。
但是作为一个用户来说 使用这种方法的学习成本太高了 我们更需要一个完整的线程库
所以说一些应用级的开发工程师就在应用层对于轻量级的Linux接口进行封装成为了我们经常使用的原生线程库pthread库。

线程的数据

线程的数据分为私有的数据和共有的数据,在同一个进程就决定了多个线程的全部数据不会都是私有的,而在同一个进程的多个线程就决定了必然有共有的部分。

线程的私有数据
  • 线程ID 这个很好理解 因为我们要使用线程ID来区分每个线程
  • 一组寄存器 这组寄存器用来保存线程的上下文信息
  • 栈 每个线程都有临时的数据需要压栈 如果不区分那数据就全乱了
  • 信号屏蔽字
  • 调度优先级
线程的共有数据

因为多个线程是在同一个进程地址空间中 所以说进程地址空间的代码段和数据段都是共享的

  • 如果定义一个函数 在各线程中都可以调用
  • 如果定义一个全局变量 在各线程中都可以访问到

除此之外 各线程还共享以下进程资源和环境

  • 文件描述符表 (进程打开一个文件后其他线程也能够看到)
  • 每种信号的处理方式(SIG_IGN、SIG_DFL或者自定义的信号处理函数)
  • 当前工作目录(cwd)
  • 用户ID和组ID等等

看看猪跑

前面讲了这么多,接下来我们先创建一个线程,然后让它跑一跑看看。
再写代码之前还要介绍一个创建线程的函数,它也是pthread库中的。
它就是pthread_create函数

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
返回值:线程创建成功返回0 失败返回错误码这里值得注意的是在线程库中 几乎所有的返回值都是成功返回0 失败返回错误码
参数说明:thread:获取创建成功的线程ID 该参数是一个输出型参数attr: 用于设置创建线程的属性 如果我们传入NULL则设置为默认属性start_routine:这是一个函数地址 传入我们想要这个线程执行的函数arg: 传给线程例程的参数 (默认是void* 类型 记得类型强转不然会报警告)

下面是猪跑 : )
makefile

mycode:mycode.ccg++ -o $@ $^ -l pthread.PHONY:cleanclean:rm -f mycode

需要注意的是,有些机器上面不加-l pthread在运行的时候会报错,这是因为找不到库文件所导致的。
mycode.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>void* run_thread(void* args)
{char* msg = (char*)args;while(1){printf("I'm a thread my msg is:%s\n" , msg);sleep(1);}
}int main()
{pthread_t tid;pthread_create(&tid ,NULL ,run_thread ,(void*)"thread 1");while(1){printf("I'm main thread\n");sleep(1);}return 0;
}

上面代码的意思是我们创建一个子线程 这个线程不停的打印参数发送过去的消息 同时我们的主进程不停的打印另外的信息
最后的结果如下:
image.png
我们可以看到两个循环在同时进行!!
以前可从来没有见过这样的情况!!
使用ps -aL查看轻量级进程
image.png
我们可以看到多了两个进程但是他们的PID是一样的,但是它们的LWP却不同
其实在操作系统调度的时候看的就是LWP
但是之间学进程的时候说操作系统调度的时候看的是PID
难道说错了?
实际上都是对的,在当时的语境下,我们只学过单进程执行流,此时进程就只对应着一个线程,此时的PID等于LWP,所以怎么说也没问题。
但是在现在学了线程以后,我们就要注意看的什么情况下了。

线程的优缺点(了解)

线程的优点

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

计算密集型 执行流的大部分任务 主要以计算为主 比如加密解密 大数据查找等
IO密集型 执行流的大部分任务 主要以IO为主 比如刷磁盘 访问数据库 访问网络等

线程的缺点

  • 性能损失: 一个很少被外部事件阻塞的计算密集型线程往往无法与其他线程共享同一个处理器 如果计算密集型线程的数量比可用的处理器多 那么可能会有较大的性能损失 这里的性能损失指的是增加了额外的同步和调度开销 而可用的资源不变
  • 健壮性降低: 编写多线程需要更全面更深入的考虑 在一个多线程程序里 因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的 换句话说 线程之间是缺乏保护的
  • 缺乏访问控制: 进程是访问控制的基本粒度 在一个线程中调用某些OS函数会对整个进程造成影响
  • 编程难度提高: 编写与调试一个多线程程序比单线程程序困难得多
线程异常

如果单个线程出现异常 比如说出现除零错误等 有可能会导致整个进程崩溃
造成这样的原因是 操作系统发送信号是向进程发送的

线程用途

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

相关文章:

《Linux从练气到飞升》No.25 Linux中多线程概念

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…...

2021~2023年度长垣起重机博览会最佳产品彩页(修订中)

1.河南恒达 比较完善的起重量限制器产品线分类&#xff0c;提供了监控参数一览表。 2.沪源电机 详细的电机参数&#xff0c;这基本上可以作为电机发展的历史资料来搜集。 3.英威腾 详细的变频器功能 4.杭州浙起 详尽的电动葫芦结构展示&#xff0c;电动葫芦参数展示 5.…...

OpenCV标定演示,及如何生成标定板图片

标定的程序在官方的源码里有&#xff0c; opencv-4.5.5\samples\cpp\tutorial_code\calib3d\camera_calibration 很多小白不知道怎么跑起来&#xff0c;这个也怪OpenCV官方&#xff0c;工作没做完善&#xff0c;其实的default.xml是要自己手动改的&#xff0c;输入的图片也要…...

python venv 虚拟环境使用

查看py版本python --version 创建虚拟环境 venvdemopython -m venv venvdemo 启动虚拟环境创建好虚拟环境后&#xff0c;当前目录会出现 venvdemo文件夹 cd envdemo\Scripts 执行 ./activate 文件 进入虚拟环境 关闭虚拟环境deactivate 如何查看Python虚拟环境位置python -c …...

useCallback和useMemo的区别?

文章目录 前言useCallbackuseMemouseCallback除了缓存回调函数还可以做什么操作&#xff1f;后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;react.js &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0…...

Angular组件生命周期详解

当 Angular 实例化组件类 并渲染组件视图及其子视图时&#xff0c;组件实例的生命周期就开始了。生命周期一直伴随着变更检测&#xff0c;Angular 会检查数据绑定属性何时发生变化&#xff0c;并按需更新视图和组件实例。当 Angular 销毁组件实例并从 DOM 中移除它渲染的模板时…...

Redsync 多 Redis 实例使用 demo

完整代码传送门 package mainimport ("context""fmt""net/http""redis-distributed-lock/redis_client""strconv""github.com/go-redsync/redsync/v4""github.com/go-redsync/redsync/v4/redis/goredis/v9&…...

Docker(1)——安装Docker以及配置阿里云镜像加速

目录 一、简介 二、安装Docker 1. 访问Docker官网 2. 卸载旧版本Dokcer 3. 下载yum-utils&#xff08;yum工具包集合&#xff09; 4. 设置国内镜像仓库 5. 更新yum软件包索引 6. 安装Docker 7. 启动Docker 8. 卸载Docker 三、阿里云镜像加速 1. 访问阿里云官网 2. …...

MCU HardFault_Handler调试方法

一.获取内核寄存器的值 1.在MDK的DEBUG模式下&#xff0c;当程序出现跑飞后&#xff0c;确定卡死在HardFault_Handler中断处 2. 通过Register窗口读取LR寄存器的值来确定当前系统使用堆栈是MSP还是PSP LR寄存器值堆栈寄存器0xFFFFFFF9MSP寄存器0xFFFFFFFDPSP寄存器 如下图所…...

【深度学习】AUTOMATIC1111 / stable-diffusion-webui docker

代码&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui/ CUDA 11.8 制作了一个镜像&#xff0c;可以直接开启stable diffusion的web ui 服务。 确定自己的显卡支持CUDA11.8&#xff0c;启动此镜像方式&#xff1a; docker run -it --networkhost --gpu…...

[Hive] 查询结果保存

文章目录 1.插入新表追加 2.插入hdfs文件系统 1.插入新表 使用INSERT OVERWRITE语句的情况&#xff1a; 整个表&#xff1a;可以使用INSERT OVERWRITE TABLE table_name语句将查询结果直接覆盖整个表中的数据。 INSERT OVERWRITE TABLE table_name SELECT * FROM ...特定分区…...

Es中出现unassigned shards问题解决

1、一般后台会报primary shard is not active Timeout: … 出现这种问题表示该索引是只读了&#xff0c;没办法进行shard及存储操作&#xff0c;优先排除是系统存储盘满了 2、通过监控工具查看(cerebro) 发现该索引shard 1 损坏 也可以通过命令进行查看 GET _cluster/allo…...

RT-DERT:在实时目标检测上,DETRs打败了yolo

文章目录 摘要1、简介2. 相关研究2.1、实时目标检测器2.2、端到端目标检测器2.3、用于目标检测的多尺度特征 3、检测器的端到端速度3.1、 NMS分析3.2、端到端速度基准测试 4、实时DETR4.1、模型概述4.2、高效的混合编码器4.3、IoU-aware查询选择4.4、RT-DETR的缩放 5、实验5.1、…...

uniapp/H5富文本复制文本功能

代码实现&#xff1a; copy() {let replacedContent this.form.resTaskBaseInfoDetail.content;let text readHtml(replacedContent)// #ifdef H5let textarea document.createElement("textarea")textarea.value texttextarea.readOnly "readOnly"d…...

通付盾Web3专题 | 智能账户:数字时代基础单元

2008年10月31日&#xff0c;中本聪&#xff08;Satoshi Nakamoto&#xff09;在P2P foundation 网站发布比特币白皮书《比特币&#xff1a;一种点对点的电子现金系统》。转眼距比特币白皮书发布已过去15年。2009年1月比特币网络正式推出&#xff0c;当时每个比特币的价格仅为0.…...

java网上阅读网站系统eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 网上阅读网站系统是一套完善的web设计系统&#xff0c;对理解JSP java SSM框架 mvc编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&a…...

人工智能基础_机器学习007_高斯分布_概率计算_最小二乘法推导_得出损失函数---人工智能工作笔记0047

这个不分也是挺难的,但是之前有详细的,解释了,之前的文章中有, 那么这里会简单提一下,然后,继续向下学习 首先我们要知道高斯分布,也就是,正太分布, 这个可以预测x在多少的时候,概率最大 要知道在概率分布这个,高斯分布公式中,u代表平均值,然后西格玛代表标准差,知道了 这两个…...

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化 前言一、GSYVideoPlayer&#x1f525;&#x1f525;&#x1f525;是什么&#xff1f;二、简单使用1.First、在project下的build.gradle添加2.按需导入3. 常用代码 rtsp流的优化大功告成 总结 前言 本文介绍&#xff0c;…...

安卓手机数据恢复工具 DiskDigger Pro 中文版-适用于已获得 root 权限的设备!可以从您的存储卡或内存恢复数据

可以从您的存储卡或内存中取消删除和恢复丢失的照片、文档、视频、音乐等。 无论您是不小心删除了文件&#xff0c;还是重新格式化了存储卡&#xff0c;DiskDigger 强大的数据恢复功能都可以找到您丢失的文件并让您恢复它们。 注意&#xff1a;如果您的设备未获得 root 权限&a…...

Python 生成Android不同尺寸的图标

源代码 # -*- coding: utf-8 -*- import sys import os import shutil from PIL import Imagedef generateAndroidIcons():imageSource icon.pngicon Image.open(imageSource)sizes [(android/drawable,512),(android/drawable-hdpi,72),(android/drawable-ldpi,36),(andro…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

在Zenodo下载文件 用到googlecolab googledrive

方法&#xff1a;Figshare/Zenodo上的数据/文件下载不下来&#xff1f;尝试利用Google Colab &#xff1a;https://zhuanlan.zhihu.com/p/1898503078782674027 参考&#xff1a; 通过Colab&谷歌云下载Figshare数据&#xff0c;超级实用&#xff01;&#xff01;&#xff0…...