【Linux】线程ID

大致草稿——————————

思维导图

学习目标

一、线程ID的理解

1.1 引出对tid的理解

我们先来创建一个线程复习一下线程的函数:

pthread_t tid;
// 创建一个线程
pthread_create(&tid, nullptr, threadrun, (void*)"thread-1");
// 打印出新线程的tid
std::cout << "new pthread tid:" << tid << std::endl;
// 进行线程的暂停
pthread_join(tid, nullptr);
// 线程执行的任务函数
void* threadrun(void* args)
{std::string name = static_cast<const char*>(args);while (true){std::cout << name << " is runing, tid:" << pthread_self() << std::endl;sleep(1);}
}
// 将一个数字转换为十六进制的字符串
std::string ToHEX(pthread_t tid)
{char id[128];snprintf(id, sizeof id, "0x%lx", tid);return id;
}

我们可以通过代码执行结果和ps -aL来查看这个线程的lwp和线程ID是不同的。 

       通过上述现象,我们发现这个线程的Iwp,给用户提供的线程ID是不同的,这个两个数字不是一个东西,线程ID是由pthread库自己维护一个值。举个例子,我们的身份证、学号是由谁给我们发送的,是由管理我们的对象生成的,因此在这个库中自然也是要对线程的管理。

总结:

  • 线程ID是一个地址
  • pthread库提供唯一的线程ID,并且对线程进行管理

理解库: 

       pthread库是一个文件,我们自己写的可执行程序也是一个文件,他们都存放在磁盘中。我们需要将可执行程序加载到内存中,将数据和代码加载到内存中,CPU区进行调度,在这个客户可执行程序中,我们如果想要创建线程,需要使用pthread函数,需要将这个pthread库加载到内存中,映射到进程的地址空间。

库如何做到对线程进行管理?

线程的局部变量:

在全局变量中,所有的线程都可以看到这个局部变量,如果我们使用__pthread来修饰全局变量,会使所有的线程在对应的线程的局部变量中都有一份gval打印出来的地址也是不一样的。

线程有一个属性:栈的大小(pthread_attr_t)

tid是一个虚拟地址,在我们的地址空间中一个线程对应的一个线程控制块。线程的ID本质是线程控制块的地址。 

二、对线程的封装

在学习完对tid的理解后,我们来进行学习对线程的封装,用类将线程的几个函数和属性封装起来。

// 线程的属性
std::string _name;
pthread_t _tid;
bool is_running;
func_t _func;
void Excute();mThread(const std::string name, func_t func);: _name(name), _func(func)static void *ThreadRoutine(void *args); ;bool Start();std::string status();void Stop();void Join();std::string Name();~mThread();  

接下来,我们来封装一下其函数:

2.1.1 构造函数

mThread(const std::string name, func_t func): _name(name), _func(func)
{std::cout << "create " << name << " done" << std::endl;
}

2.1.2 开始函数

void Excute()
{std::cout << _name << " is running" << std::endl;is_running = true;_func(_name);is_running = false;
}// 类内函数隐含的隐藏了this指针
static void *ThreadRoutine(void *args) // 新线程都会执行
{//_func(_name);mThread *self = static_cast<mThread *>(args); // 获得了我们对应的当前对象self->Excute();return nullptr;
}bool Start()
{int n = ::pthread_create(&_tid, nullptr, ThreadRoutine, this);if (n != 0)return false;return true;
}

2.1.3 暂停函数

void Stop()
{if (is_running){::pthread_cancel(_tid);is_running = false;std::cout << _name << " Stop" <<std::endl;}
}

2.1.4 取消函数

void Join()
{::pthread_join(_tid, nullptr);std::cout << _name << " Join" << std::endl;
}

2.1.5 测试代码

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <vector>
#include "Thread.hpp"using namespace Mypthread;void Print(const std::string &name)
{int cnt = 1;while (true){std::cout << "name:" << name << " is runing, cnt:" << cnt++ << std::endl;sleep(1);}
}int main()
{std::vector<mThread> mThreads;for(int i = 0; i < 10; i++){std::string name = "thread-" + std::to_string(i + 1);mThreads.emplace_back(name, Print);sleep(1);}// 统一启动for(auto& k : mThreads){k.Start();}sleep(10);// 统一停止for(auto& k : mThreads){k.Stop();}// 统一取消for(auto& k : mThreads){k.Join();}return 0;
}// int main()
// {
//     // 线程的开始
//     const std::string name = "thread-1";
//     mThread t(name, Print);
//     // std::cout << "status" << t.status() << std::endl;
//     t.Start();
//     std::cout << t.Name() << " ,status:" << t.status() << std::endl;
//     sleep(10);
//     std::cout << t.Name() << " ,status:" << t.status() << std::endl;//     t.Stop();
//     sleep(1);
//     std::cout << t.Name() << " ,status:" << t.status() << std::endl;//     t.Join();
//     std::cout << t.Name() << " ,status:" << t.status() << std::endl;
//     return 0;
// }

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

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

相关文章

怎么花草识别?方法有三种!

怎么花草识别&#xff1f;在这个五彩斑斓的世界里&#xff0c;花草是我们生活中不可或缺的一部分。它们点缀着我们的环境&#xff0c;为我们带来无尽的美丽与惊喜。然而&#xff0c;面对众多的花草种类&#xff0c;你是否曾感到困惑和迷茫&#xff0c;不知道如何识别它们&#…

VIO System 丨适用于控制器开发前期的测试系统

VIO综述 嵌入式软件的HIL测试需要复杂的测试系统及完整的ECU硬件&#xff0c;这导致通常只能在开发流程的后期阶段进行测试。全新推出的低成本解决方案VIO System&#xff0c;使得在开发前期不仅可以进行总线通讯测试&#xff0c;也可以同时进行I/O信号测试。 该系统旨在通过…

LabVIEW版本控制

LabVIEW作为一种流行的图形化编程环境&#xff0c;在软件开发中广泛应用。有效地管理版本控制对于确保软件的可靠性和可维护性至关重要。LabVIEW提供了多种方式来管理VI和应用程序的修订历史&#xff0c;以满足不同规模和复杂度的项目需求。 LabVIEW中的VI修订历史 LabVIEW内置…

docker安装Mysql5.7版本

首先Linux系统已经安装好了docker应用。 1.搜索镜像 docker search mysql 2.拉取5.7的镜像 总之,选starts最多的那个就对了。 docker pull mysql:5.7 ~ docker pull mysql:5.7 5.7: Pulling from library/mysql fc7181108d40: Downloading [============> …

mysql创建数据表----centos7.9

mysql创建数据表 查看存在的表 show tables;我这里还未创建任何表所以是这样的 如有是这样 若没有表需要先创建一个表 CREATE DATABASE tb_your_name&#xff1b;创建字段及属性 CREATE TABLE tb_laws_regulations (id INT AUTO_INCREMENT PRIMARY KEY, -- 文件唯…

柯桥外贸俄语哪里可以学,零基础俄语培训

Де́лать 做 из му́хи 从苍蝇 слона́ 大象 我觉得汉语里有一个很合适的词来形容&#xff1a; Де́лать из му́хи слона́ 就是 小题大做&#xff0c;本来是一件很小的事&#xff0c;却把它形容成天大的事一样 Хвтит де́…

【UE5.1 角色练习】10-物体抬升、抛出技能 - part2

目录 前言 效果 步骤 一、让物体缓慢的飞向手掌 二、向着鼠标方向发射物体 前言 在上一篇&#xff08;【UE5.1 角色练习】08-物体抬升、抛出技能 - part1&#xff09;的基础上继续完成角色将物体吸向手掌&#xff0c;然后通过鼠标点击的方向来发射物体的功能。 效果 步骤…

代码随想录算法训练营第三十二 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II 讲解链接&#xff1a;https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%90%8E%E6%9C%80%E5%A4%A7%E5%8C%96%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C.html 简单思路&#xff1a;逐个计算连续两天的股票差值&#xff0c;sum初始为零&…

【并查集】专题练习

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板 836. 合并集合 - AcWing题库 #include<bits/stdc.h> using lllong long; //#define int ll const int N1e510,mod1e97; int n,m; int p[N],sz[N]; int find(int a) {if(p[a]!a) p[a]find(p[a]);return p[a…

第十八讲:联合和枚举

第十八讲&#xff1a;联合和枚举 1.联合体&#xff08;共用体&#xff09;1.1联合体的声明1.2联合体大小的计算1.3联合体的特点1.4联合体的使用1.4.1联合体的直接使用1.4.2联合体直接使用的优化方法1.4.3联合体成员中含有数组的使用1.4.4使用联合体判断当前机器是大端排序&…

K8s(Kubernetes)常用命令

大家好&#xff0c;当谈及容器编排工具时&#xff0c;Kubernetes&#xff08;常简称为K8s&#xff09;无疑是当今最受欢迎和广泛使用的解决方案之一。作为一个开源的容器编排平台&#xff0c;Kubernetes 提供了丰富的功能&#xff0c;可以帮助开发人员和运维团队管理、部署和扩…

电商分析@电商数据与运营优化

电商数据分析与运营优化是指通过对电商平台的各种数据进行深入分析&#xff0c;以发现潜在的问题和机会&#xff0c;并采取相应的优化措施&#xff0c;提高电商运营效率和盈利能力。 首先&#xff0c;电商数据分析需要收集和整理各类数据&#xff0c;包括销售数据、用户数据、流…

实战16:基于apriori关联挖掘FP-growth算法挖掘关联规则的手机销售分析-代码+数据

直接看视频演示: 基于apriori关联挖掘关联规则的手机销售分析与优化策略 直接看结果: 这是数据展示: 挖掘结果展示: 数据分析展示:

利用WK2168实现串口服务器

ESP32 SPI与WK2168实现串口服务器 概述系统组成代码概述 一些老设备通过RS485采集数据,如果在一个系统中采用几个RS485设备可能是一个不错的选择,但要是使用46个RS485数据采集设备为一个PLC提供外部数据,系统的性能就很难有保障了。通过一个串口服务器实现看来是一个好的选…

智慧校园有哪些特征

随着科技的飞速进步&#xff0c;教育领域正经历着一场深刻的变革。智慧校园&#xff0c;作为这场变革的前沿代表&#xff0c;正在逐步重塑我们的教育理念和实践方式。它不仅仅是一个概念&#xff0c;而是一个集成了物联网、大数据、人工智能等先进技术的综合生态系统&#xff0…

SpringBoot源码(自动装配、内嵌Tomcat)

文章目录 依赖管理pom依赖管理Web依赖自定义starter 一、WebMvcAutoConfiguration1.1 Filter1.2 Interceptor 二、源码解析2.1 SpringApplication2.1.1 构造方法1、填充webApplicationType2、自动装配Initializers3、自动装配Listeners 2.1.2 run(args) 2.2 SpringApplicationR…

AI边缘计算盒子在智慧交通的应用

方案背景 随着经济增长&#xff0c;交通出行需求大幅增长&#xff0c;但道路建设增长缓慢&#xff0c;交通供需矛盾日益显著&#xff0c;中心城区主要道路高峰时段交通拥堵严重&#xff0c;道路交通拥堵逐渐常态化&#xff0c;成为制约城市可持续发展的重要因素之一。 痛点问题…

web 前端开发技术---网页的制作

这是一个网页代码 上年包含了电子邮件&#xff0c;选项建 等等 分享给大家 <!-- prj_7_1.html --> <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8"><title>留言板设计</title><style type&…

【C++】入门(一):命名空间、缺省参数、函数重载

目录 一、关键字 二、命名空间 问题引入(问题代码)&#xff1a; 域的问题 1.::域作用限定符 的 用法&#xff1a; 2.域的分类 3.编译器的搜索原则 命名空间的定义 命名空间的使用 举个&#x1f330;栗子&#xff1a; 1.作用域限定符指定命名空间名称 2. using 引入…

K210视觉识别模块学习笔记3:内存卡写入拍摄图片_LED三色灯的操作_按键操作_定时器的配置使用

今日开始学习K210视觉识别模块: LED三色灯的操作_按键操作_定时器的配置使用_内存卡写入拍摄图片 亚博智能的K210视觉识别模块...... 本文最终目的是编写一个按键拍照的例程序&#xff1a; 为以后的专用场景的模型训练做准备&#xff0c;因为训练自己的模型需要大量的图片&a…