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

理解线程id和简单封装原生线程库

一、理解线程id

首先我们要知道给用户提供的线程id不是内核里面LWP(轻量级进程id),而是pthread库自己维护的一个唯一值。

我们理解为什么线程id不是内核里面LWP,因为用户没有权限使用内核里面的字段,那是专门给OS管理线程用的。

但是为什么要pthread库来帮我们用户维护用户级线程id呢?

因为Linux内核根本就不存在线程的概念,所谓用户口中的线程在Linux眼里就是轻量级进程,之后理解不在赘述具体参考文章http://t.csdnimg.cn/jTGGP中pthread库介绍。

内核级理解:

所以我们清楚的看到返回给用户的线程id就是一个线程控制块在虚拟地址空间的起始位置。

类比FILE对象,其实就在c标准库中,返回的是FILE*就是地址。

所以 pthread_join() 函数就是通过tid找到存在虚拟地址空间中的线程结构体对象,把里面的退出信息拷贝出来返回。

操作系统内示意图:

二、简单封装原生线程库

thread.hpp

#pragma once
#include<pthread.h>
#include<iostream>
#include<string>
using namespace std;namespace Thread
{//线程执行方法typedef void(*func_t)(const string& name);class Thread{public://线程执行方法void Excute(){cout << _name << " is running" << endl; _isrunning = true;_func(_name);_isrunning = false;}public:Thread(const string& name, func_t func):_name(name),_func(func){cout << "create " << name << " done" << endl; }//线程执行回调方法//设成静态方法,函数就不会自带this指针,类型就匹配上了//但是此时就无法调类的回调函数,在create函数中传参即可static void* ThreadRoutine(void* args){//获得当前线程对象Thread* self = static_cast<Thread*>(args);//调用线程执行方法self->Excute();return nullptr;}bool Start(){int n = ::pthread_create(&_tid, nullptr, ThreadRoutine, this);if (n != 0)return false;return true;}string Status(){if(_isrunning) return "running";else return "sleep";}string GetName(){return _name;}void Stop(){if(_isrunning = true){::pthread_cancel(_tid);_isrunning = false;cout << _name << " stop" << endl; }}void Join(){if(!_isrunning){::pthread_join(_tid, nullptr);cout << _name << " join done" << endl; }}~Thread(){}private:string _name;pthread_t _tid;bool _isrunning = false;func_t _func; //线程执行的回调函数};
}

main.cc

#include<iostream>
#include"thread.hpp"
#include<unistd.h>
#include<vector>
using namespace Thread;
using namespace std;void Print(const string& name)
{int cnt = 0;while(1){cout << name << " is running, cnt: " << cnt++ << endl;sleep(1);}
}const int num = 10;int main()
{//创建线程vector<Thread::Thread> threads;for(int i = 0; i < num; i++){string name = "thread-" + to_string(i + 1);threads.emplace_back(name, Print);sleep(1);}//统一启动for(auto& thread : threads){thread.Start();}sleep(10);//统一结束for(auto& thread : threads){thread.Stop();}//统一回收for(auto& thread : threads){thread.Join();}// Thread::Thread t("thread-1", Print);// t.Start();// cout << t.GetName() << " status: " << t.Status() << endl;// sleep(10);// cout << t.GetName() << " status: " << t.Status() << endl;// t.Stop();// sleep(1);// cout << t.GetName() << " status: " << t.Status() << endl;// t.Join();// cout << "join done" << endl;return 0;
}

三、线程的局部存储

对于一个全局变量,一个进程中任意线程都能进行修改,另外的线程也可以看到变化,因为线程共享进程的大部分数据。

在LInux中我们用 __thread修饰全局变量(只能修饰内置类型)就能让全局变量在所有线程各有一份,地址也不同,这就能实现每一个线程都有属于自己的变量,这就是线程的局部存储。

相关文章:

理解线程id和简单封装原生线程库

一、理解线程id 首先我们要知道给用户提供的线程id不是内核里面LWP&#xff08;轻量级进程id&#xff09;&#xff0c;而是pthread库自己维护的一个唯一值。 我们理解为什么线程id不是内核里面LWP&#xff0c;因为用户没有权限使用内核里面的字段&#xff0c;那是专门给OS管理…...

Unified 阻抗控制 architecture、framework、approach

Unified 阻抗控制&#xff08;Unified Impedance Control&#xff09;作为一种控制策略&#xff0c;其architecture&#xff08;架构&#xff09;、framework&#xff08;框架&#xff09;和approach&#xff08;方法&#xff09;为&#xff1a; 一、Unified 阻抗控制 Archite…...

Java后端面试题(mq相关)(day9)

目录 为什么用MQ&#xff1f; 异步 、削峰、解耦1. 异步处理2. 解耦3. 削峰填谷 Exchange类型什么是死信队列&#xff1f;如何保证消息的可靠性&#xff1f;RabbitMQ中如何解决消息堆积问题?RabbitMQ中如何保证消息有序性?如何防止消息重复消费&#xff1f;(如何保证消息幂等…...

算法-华为OD机试-识别有效的IP地址和掩码并进行分类统计

1.描述 见牛客网 https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a74356822. 分析 根据题目要求&#xff0c;分为以下几步 1. 提取IP地址和子网掩码 我们首先需要拆分输入的每一行&#xff0c;分别提取IP地址和子网掩码&#xff0c;并检查它们的合法性。 2.…...

钉钉开发网页应用JSAPI前端授权鉴权nodejs实现

钉钉开发网页应用JSAPI前端授权鉴权nodejs实现 使用钉钉进行H5网页开发的时候&#xff0c;需要调用一些钉钉提供具有原生能力的api&#xff0c;要调用这些api需要进行jsapi授权。 详见官方文档&#xff08;可选&#xff09;开发网页应用前端 - 钉钉开放平台 (dingtalk.com) 官方…...

uniapp 自定义全局弹窗

自定义全局弹窗可在js和.vue文件中调用&#xff0c;unipop样式不满足&#xff0c;需自定义样式。 效果图 目录结构 index.vue <template><view class"uni-popup" v-if"isShow"><view class"uni-popup__mask uni-center ani uni-cust…...

element+-ui图片无法使用--安装

element-ui图片无法使用 安装npm install element-plus/icons-vue 注册 // main.jsimport * as ElementPlusIconsVue from element-plus/icons-vueconst app createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, compo…...

Python编码系列—Python ORM(对象关系映射):高效数据库编程实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…...

一次日志记录中使用fastjson涉及到ByteBuffer的教训

背景 目前本人在公司负责的模块中&#xff0c;有一个模块是负责数据同步的&#xff0c;主要是将我们数据产线使用的 AWS Dynamodb 同步的我们的测试QA 的环境的 MongoDB 的库中&#xff0c;去年开始也提供了使用 EMR 批量同步的功能&#xff0c;但是有时候业务也需要少量的数据…...

掌握TCP连接管理与流量控制:从零开始

文章目录 1. TCP连接管理1.1 三次握手&#xff08;Three-way Handshake&#xff09;1.2 四次挥手&#xff08;Four-way Handshake&#xff09;1.3 TCP连接管理的重要性 2. TCP流量控制2.1 滑动窗口&#xff08;Sliding Window&#xff09;2.2 拥塞控制&#xff08;Congestion C…...

python提取b站视频的音频(提供源码

如果我想开一家咖啡厅&#xff0c;那么咖啡厅的音乐可得精挑细选&#xff01;又假设我非常喜欢o叔&#xff0c;而o叔只在b站弹钢琴&#xff0c;那这时候我就得想方设法把b站的视频转为音频咯&#xff01; 一、首先打开网页版bilibili&#xff0c;按F12&#xff1a; 二、刷新页面…...

嵌入式Linux ,QT5 鼠标键盘设备参数指定环境变量的方法

根文件系统中&#xff0c;一般用mdev来管理设备&#xff0c;不像udev方便&#xff0c;有时候在执行rcS脚本的时候因为&#xff0c;太快&#xff0c;有些设备比如鼠标还没在/dev/input中生成设备文件&#xff0c;最好使用前用mdev -s扫描并等待几秒钟&#xff0c;然后就可以在in…...

C语言钥匙迷宫2.0

目录 开头程序程序的流程图程序游玩的效果结尾 开头 大家好&#xff0c;我叫这是我58。废话不多说&#xff0c;咱们直接开始。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <Windows.h> enum color {Y,B,R …...

【多线程】初步认识Thread类及其应用

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;多线程 / javaEE初阶 上篇文章我们简单介绍了什么是进程与线程&#xff0c;以及他们之间的区别与联系&#xff0c;实际应用中还是以多线程编程为主的&#xff0c;所以这篇文章就让我们更加深入地去剖…...

algorithm算法库学习之——划分操作和排序操作

algorithm此头文件是算法库的一部分。本篇介绍划分操作和排序操作。 划分操作 is_partitioned (C11) 判断范围是否已按给定的谓词划分 (函数模板) partition 将范围中的元素分为两组 (函数模板) partition_copy (C11) 复制一个范围&#xff0c;将各元素分为两组 (函数模板) st…...

XSS实验记录

目录 XXS地址 实验过程 Ma Spaghet Jeff Ugandan Knuckles Ricardo Milos Ah Thats Hawt Ligma Mafia Ok, Boomer XXS地址 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 实验过程 Ma Spaghet 要求我们弹出一个alert(1337)sandbox.pwnfuncti…...

Cortex-A7的GIC(全局中断控制器)使用方法(7):基于stm32MP135的GIC配置中断效果测试

0 参考资料 STM32MP13xx参考手册.pdf&#xff08;RM0475&#xff09; ARM Generic Interrupt Controller Architecture version 2.0 - Architecture Specification.pdf 1 GIC配置中断效果测试 前面我们已经实现了GIC的配置&#xff0c;为了验证GIC是否配置有效&#xff0c;本例…...

c++动态数组new和delete

文章目录 动态数组的使用大全1. **基本创建和初始化**2. **动态调整大小**3. **动态数组的使用与标准库 std::vector**4. **动态数组作为函数参数**输出 5. **使用动态数组存储用户输入** 动态数组的使用大全 1. 基本创建和初始化 示例&#xff1a; #include <iostream&g…...

Redis热点知识速览(redis的数据结构、高性能、持久化、主从复制、集群、缓存淘汰策略、事务、Pub/Sub、锁机制、常见问题等)

Redis是一个开源的、使用内存作为存储的、支持数据结构丰富的NoSQL数据库。它的高性能、灵活性和简单易用使其在许多场景下成为首选的缓存解决方案。以下是Redis的常见和热点知识总结。 数据结构 Redis支持五种基本数据结构&#xff1a; String&#xff1a;字符串是Redis中最…...

【C++浅析】lambda表达式:基本结构 使用示例

基本结构 [捕获列表](参数列表) -> 返回类型 { // 函数体 } 捕获列表 ([ ]): 用于指定外部变量的捕获方式。可以&#xff1a; 通过值捕获&#xff1a;[x]通过引用捕获&#xff1a;[&x]捕获所有变量通过值&#xff1a;[]捕获所有变量通过引用&#xff1a;[&]自…...

2025年CMS怎么选?从传统到无头再到AI原生,一份深度选型指南

快速选型参考如果你需要直接的建议&#xff0c;这里是一个基于场景的简明对照&#xff1a;个人博客、小型内容站点&#xff1a;WordPress&#xff0c;生态成熟&#xff0c;主题插件丰富&#xff0c;上手门槛低。多终端内容分发&#xff08;App、小程序、Web同步&#xff09;&am…...

嵌入式 C 语言宏的高级编程技巧~

嵌入式情报局 嵌入式 C 语言宏的高级编程技巧~ 用VSCode打造嵌入式 Linux 开发的终极 IDE...

回流平台深耕闲置翡翠流通,以数字化服务激活珠宝产业新动能

据中国珠宝玉石首饰行业协会数据&#xff0c;我国珠宝玉石首饰产业市场规模持续扩大&#xff0c;翡翠玉石作为第二大珠宝消费品类&#xff0c;市场存量可观。与此同时&#xff0c;发达国家二手高端消费品交易占整个高端消费品市场的20%至30%&#xff0c;我国目前占比约5%&#…...

懒人必备!OpenClaw 汉化版一键配置上手教程

一、Windows 11 安装 OpenClaw 必看说明 OpenClaw&#xff08;国内用户昵称"小龙虾"&#xff09;是一款广受欢迎的开源本地AI助手&#xff0c;GitHub星标数已超28万。它集成了多项实用功能&#xff1a;电脑自动操控、智能文件管理、浏览器自动化以及办公流程自动化等…...

Eviews面板数据建模保姆级教程:从Hausman检验到模型选择,一次讲透固定效应与随机效应

Eviews面板数据建模实战指南&#xff1a;从数据导入到模型选择的完整流程 面板数据分析作为计量经济学中的重要工具&#xff0c;能够同时捕捉时间和个体维度的信息。对于刚接触Eviews的研究者来说&#xff0c;如何正确建立面板模型往往令人困惑——从数据准备到模型选择&#x…...

单片机显示开发避坑:手把手教你用C语言搞定RGB888、RGB565和RGB666的颜色格式转换

单片机显示开发实战&#xff1a;C语言高效处理RGB888、RGB565与RGB666格式转换 当你在STM32或ESP32上驱动一块LCD屏幕时&#xff0c;是否遇到过这样的场景&#xff1a;精心设计的UI界面在屏幕上显示时&#xff0c;颜色却变得怪异扭曲&#xff1f;这往往源于颜色格式的错配——你…...

基于RT-Thread与N32G457的三通道UART透明监控网关设计与实现

1. 项目概述与核心需求解析在嵌入式开发&#xff0c;特别是涉及工业控制、智能硬件或者多设备联调的现场&#xff0c;我们经常会遇到一个非常实际的痛点&#xff1a;如何在不干扰原有通信链路的前提下&#xff0c;实时监控两台设备之间的串口数据交互。无论是调试新的通信协议&…...

舞蹈学论文降AI工具免费推荐:2026年舞蹈学研究毕业论文知网维普99.26%亲测达标4.8元完整方案

舞蹈学论文降AI工具免费推荐&#xff1a;2026年舞蹈学研究毕业论文知网维普99.26%亲测达标4.8元完整方案 直接给结论&#xff1a;嘎嘎降AI&#xff08;www.aigcleaner.com&#xff09;&#xff0c;4.8元&#xff0c;知网AI率55%降到5.3%&#xff0c;稳定可靠。 舞蹈学论文降A…...

保姆级教程:用Python和go-cqhttp给QQ群做个自动回复机器人(附完整代码)

从零构建智能QQ群机器人&#xff1a;Python与go-cqhttp实战指南 在社群运营中&#xff0c;自动回复机器人早已成为提升管理效率的利器。无论是处理高频咨询、新人引导&#xff0c;还是定时发布公告&#xff0c;一个配置得当的机器人能显著减轻管理员负担。本文将带你深入探索如…...

RISC-V双发射混合运算优化技术COPIFT解析

1. RISC-V双发射混合运算优化技术概述在当今处理器架构设计中&#xff0c;能效比已经超越单纯性能指标成为首要考量因素。RISC-V作为开源指令集架构&#xff0c;凭借其模块化设计和可扩展性&#xff0c;为能效优化提供了独特优势。双发射(Dual-Issue)技术通过每个时钟周期发射两…...