【Linux】线程控制(二)

【Linux】线程控制(二)

文章目录

背景

Linux中没有真正的线程概念,而是复用进程数据结构和管理算法,用进程模拟线程

只有轻量级进程,不会提供线程的调用接口,而是提供轻量级进程的系统调用接口

但是我们用户需要线程调用,所以有pthread库帮我们封装了轻量级进程调用接口,我们可以直接使用线程接口

  • 每个linux平台自带pthread库,
  • 编写多线程代码需要pthread库

线程接口

在这里插入图片描述


每个线程都有自己的ID,
⭐pthread_create不是系统调用,需链接 -pthread

🚩进程控制

快速使用一下

#include<iostream>#include<pthread.h>#include<unistd.h> using namespace std;void*threadRoutine(void*args){constchar* str=(constchar*)args; cout<<str<<endl;int cnt=5;while(cnt--){ cout<<"thread id :"<<pthread_self()<<endl;sleep(1);}}intmain(){pthread_t tid; cout<<tid<<endl;pthread_create(&tid,nullptr,*threadRoutine,(void*)"thread 1"); cout<<tid<<endl;pthread_join(tid,nullptr);return0;}
在这里插入图片描述

刚开始tid没有初始化,主线程要最后一个退出,等待子线程

线程等待默认是阻塞的,为什么不考虑异常呢?
因为单个线程如果异常,整个进程都崩溃了

int g_val=100;void*threadRoutine(void* args){constchar* str=(constchar*)args;int cnt=5;while(cnt--){printf("%s pid: %d, g_val: %d, &g_val: 0x%p \n",str,getpid(),g_val,&g_val);sleep(1); g_val++;}//pthread_exit(100) //exit(100); //不能用exit,直接把整个进程退出了return(void*)100;//退出线程}intmain(){pthread_t tid;pthread_create(&tid,nullptr,*threadRoutine,(void*)"thread 1");int cnt=5;while(cnt--){printf("main thread %d, g_val: %d, &g_val: 0x%p , create a new thread: %p \n",getpid(),g_val,&g_val, tid);sleep(1); g_val++;}sleep(2);void* set;pthread_join(tid,&set); cout<<"new thread quit success"<<(longlongint)set<<endl;return0;}
ps -aL查看所有线程
while :; do ps -aL; sleep 1;done;监控
在这里插入图片描述


可以看到两个mythread,进程pid相同,LWP(light weight process轻量化进程)不同

  • LWP在内核看来就是线程

线程ID有两种:一种是内核视角LWP,另一种线程视角pthread_t

在这里插入图片描述


两个不同的执行流,共享相同的全局变量,也可以调用相同的函数,这里发生数据冲突了,后面会讲

所以,用户级线程(线程库控制)加上内核LWP才构成Linux线程,Linux也有内核级线程
用户级执行流:LWP=1:1

在这里插入图片描述

线程计算1-100

class Reques t { public:Request(int begin,int end,const string& threadname):_begin(begin),_end(end),_threadname(threadname){} public:int _begin;int _end; string _threadname;}; class Reponse { public:Reponse(int result,int exitcode):_result(result),_exitcode(exitcode){} public:int _result;//计算结果int _exitcode;//计算结果是否可靠};void*sumRoutine(void* args)// 线程的参数和返回值,不仅仅可以传递一般参数,还可以传递自定义对象{ Request* rq=static_cast<Request*>(args);//(Request*)args; Reponse* rsp=new Reponse(0,0);if(rq->_begin>rq->_end){ rsp->_exitcode=-1;}else{for(int i=rq->_begin;i<=rq->_end;i++){ rsp->_result+=i;}} delete rq;return rsp;}intmain(){pthread_t tid; Request *rq=new Request(1,100,"thread 1");pthread_create(&tid,nullptr,*sumRoutine,rq);void* set;pthread_join(tid,&set); Reponse *rsp=static_cast<Reponse*>(set); cout<<"rsp -> _result: "<<rsp->_result<<"rsp ->_exitcode: "<<rsp->_exitcode <<endl; delete rsp;return0;}
在这里插入图片描述

🚩线程库

线程的概念是库给我们维护的,线程库中有clone回调函数将执行流给进程PCB,共享父进程资源,线程库维护线程概念,不用维护执行流,线程库注定要维护多个线程属性集合,先描述再组织

线程库要不要加载到内存?
要,加载到共享区,等于动态库

在这里插入图片描述
在这里插入图片描述

c++11多线程

C++11也支持多线程了,已经帮我们封装好了,直接用就行

voidthreadrun(){while(true){ cout <<"I am a new thead for C++"<< endl;sleep(1);}}intmain(){ thread t1(threadrun); t1.join();return0;}

Read more

Vue路由的hash模式与history模式深度解析:从原理到实战应用

Vue路由的hash模式与history模式深度解析:从原理到实战应用

Vue路由的hash模式与history模式深度解析:从原理到实战应用 引言:为什么路由模式选择如此重要? 在现代前端开发中,单页应用(SPA)已成为主流开发模式。作为Vue生态系统的核心组成部分,Vue Router提供了两种路由模式:hash模式和history模式。许多开发者在项目初始化时往往随意选择一种模式,却忽略了这两种模式在原理、应用场景和实际表现上的显著差异。 理解这两种模式的底层机制,不仅能帮助我们在技术选型时做出更明智的决策,还能在面试中展现出对前端路由系统的深入理解。本文将从底层原理出发,结合真实场景分析,带你彻底掌握Vue Router的两种路由模式。 一、基础概念解析 1.1 什么是前端路由? 在深入探讨两种模式之前,我们首先需要理解前端路由的核心概念。传统多页应用中,路由由服务器控制,每次页面跳转都需要向服务器发起请求并重新加载整个页面。而在单页应用中,路由由前端JavaScript控制,通过动态切换组件来实现页面内容的更新,无需重新加载整个页面。 // 简化的前端路由基本原理classSimpleRouter{constructor(){th

By Ne0inhk
HDFS核心组件深度解析:分布式文件系统的架构基石

HDFS核心组件深度解析:分布式文件系统的架构基石

HDFS核心组件深度解析:分布式文件系统的架构基石 * 引言:HDFS——大数据的存储基石 * 一、HDFS架构全景 * 1.1 主从架构设计 * 1.2 核心组件概览 * 二、NameNode:HDFS的"大脑" * 2.1 核心职责 * 2.2 元数据存储结构 * 2.3 内存与持久化 * 2.4 单点故障问题 * 三、DataNode:HDFS的"数据仓库" * 3.1 核心职责 * 3.2 工作流程 * 3.3 数据存储结构 * 四、Secondary NameNode:NameNode的&

By Ne0inhk
目标检测算法——YOLOV11——算法详解

目标检测算法——YOLOV11——算法详解

关键词:YOLO V11、目标检测、算法、解读、详解、教程、结构图、分析 一、主要贡献     其实到了YOLOV5 基本创新点就不太多了,主要就是大家互相排列组合复用不同的网络模块、损失函数和样本匹配策略,需要注意YOLO V5、V8 V11 都是1个公司的,其余的个人建议看看V6美团的,剩下的了解就好。     V11支持多种视觉任务:物体检测、实例分割、图像分类、姿态估计和定向物体检测(OBB)。     Yolo v11 基本和YOLOV8同源,甚至git目前都是1个,部分代码注释还是YOLOV8的,所以建议先看我写的YOLOV8相关博客,对比YOLOV8主要涉及到:     *backbone 中的使用C2f模块 变为 c3k2 模块。     *backbone 中的最后一层(sppf层)后增加了C2PSA模块。     *head 解耦头中的分类检测头两个Conv 变为 DWConv。     整体技术而言:

By Ne0inhk
【优选算法必刷100题】第011~012题(同向双指针:滑动窗口算法):最大连续1的个数 III、将 x 减到 0 的最小操作数

【优选算法必刷100题】第011~012题(同向双指针:滑动窗口算法):最大连续1的个数 III、将 x 减到 0 的最小操作数

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的算法专栏简介: 目录 011  最大连续1的个数 III 1.1  题目详解 1.2  算法原理以及代码实现 1.2.1  解法思路:滑动窗口 1.2.2  算法流程 1.2.3  代码实现 1.3  博主手记 012  将 x 减到

By Ne0inhk