【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;
// }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos-SpringBoot-配置中心

Nacos配置中心 前情回顾 上一章呢 了解并且学习了Nacos服务注册与发现 在一系列破防中走了出来Nacos服务注册完成https://blog.csdn.net/m0_68711597/article/details/139265244?spm1001.2014.3001.5502 本以为接下来会一帆风顺 一马平川 没想刚出坑 又入坑 Nacos的配置…

副业赚钱的路子有哪些?推荐15个靠谱副业和赚钱软件给你做

在这个工资永远追不上物价的时代&#xff0c;你是否也感到焦虑&#xff1f;是否想过在工作之余&#xff0c;开辟一条赚钱的副业之路&#xff1f;别急&#xff0c;今天就为你揭开副业赚钱的神秘面纱&#xff0c;带你一探究竟&#xff01; 一、宅富社任务&#xff1a;每日小任务&…

华为官网的自助申诉

代码&#xff1a;如下 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Document</title> …

Python自动化办公2.0 即将发布

第一节课&#xff1a;数据整理与清洗 第二节课&#xff1a;数据筛选、过滤与排序 第三节课&#xff1a;高级数据处理技巧 第四节课&#xff1a;数据可视化与实践案例 第五节课&#xff1a;统计分析与报表 第六节&#xff1a;常见的Excel报表 与下方的课程形成知识体系&…

【教学类-60-01】彩色消划掉01(四个数字,X*Y宫格)

背景需求&#xff1a; &#x1f9e0;思维启蒙 - 小红书注意力训练小分享-彩色划消 训练孩子的视觉辨别能力、视觉稳定性、注意力分配额能力&#x1f440; 一起来试试吧&#xff5e; #分享学习方法 #注意力训练 #专注力训练#天津 #亲子时光 #孩子成长 #思维启蒙 #数学思维启蒙 …

天工大模型:中国AI搜索巨头如何一骑绝尘?

5月&#xff0c;全球大模型领域的竞争&#xff0c;或可用“你方唱罢我方登场”来形容。 谷歌、腾讯、阿里、字节跳动等业界巨擘纷纷亮出大招。有的凭借技术底蕴实现全面升级&#xff0c;有的慷慨将大模型开源免费&#xff0c;更有甚者通过价格战掀起狂风巨浪&#xff0c;整个市…

4月啤酒品类线上销售数据分析

近期&#xff0c;中国啤酒行业正处于一个重要的转型期。首先&#xff0c;消费者对高品质啤酒的需求不断增加&#xff0c;这推动了行业向高端化、场景化和社交化的方向发展。精酿啤酒作为这一趋势的代表&#xff0c;其发展势头强劲&#xff0c;不仅满足了消费者对品质化、个性化…

解决get请求入参@NotNull验证不生效问题

get请求NotNull验证不生效 在这里插入图片描述 解决办法 在该方法的controller类上加Validated 解决get请求入参NotNull验证不生效问题

CCF-GESP 2024 四级T1相似字符串

题目描述 对于两个字符串A和B&#xff0c;如果A可以通过删除一个字符&#xff0c;或插入一个字符&#xff0c;或修改一个字符变成B&#xff0c;那么我们说A和B是相似的。 比如 apple 可以通过插入一个字符变成 applee &#xff0c;可以通过删除一个字符变成 appe &#…

基于百度智能体平台快速搭建Java学习助手

文章目录 前言什么是文新智能体平台&#xff1f;Java学习助手智能体搭建智能体效果智能体入口文新智能体体验感受 前言 一个Java初学者在学习Java时可能不知道从哪下手&#xff0c;一个工作了3年的Java开发遇到瓶颈期不知如何提升自己&#xff0c;此时&#xff0c;如果有一个老…

多环境和前后多环境实战

文章目录 一.多环境1.1 什么是多环境1.2 多环境分类1.2.1 本地环境&#xff08;自己的电脑&#xff09;1.2.2 开发环境&#xff08;远程开发&#xff09;1.2.3 测试环境1.2.4 预发布环境1.2.5 正式环境1.2.6 沙箱环境&#xff08;实验环境&#xff09; 1.3 如何实现1.3.1 抽象配…

【算法】模拟算法——替换所有的问号(easy)

题解&#xff1a;替换所有的问好(模拟算法) 目录 1.题目2.题解3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.题解 纯模拟。从前往后遍历整个字符串&#xff0c;找到问号之后&#xff0c;就⽤ a ~ z 的每⼀个字符去尝试替换即可。 3.参考代码 class Solution { pu…

Whisper-AT:抗噪语音识别模型(Whisper)实现通用音频事件标记(Audio Tagger)

本文介绍一个统一音频标记&#xff08;Audio Tagger&#xff09;和语音识别&#xff08;ASR&#xff09;的模型&#xff1a;Whisper-AT&#xff0c;通过冻结Whisper的主干&#xff0c;并在其之上训练一个轻量级的音频标记模型。Whisper-AT在额外计算成本不到1%的情况下&#xf…

构建树结构的几种方式

表结构 CREATE TABLE sys_dept (dept_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ID,pid bigint(20) DEFAULT NULL COMMENT 上级部门,sub_count int(5) DEFAULT 0 COMMENT 子部门数目,name varchar(255) NOT NULL COMMENT 名称,dept_sort int(5) DEFAULT 999 COMMENT 排…

Sapphire开发日志(三)

任务描述 本周实现并封装了模型的运行&#xff0c;需要在前端安装依赖的库&#xff0c;编写对应的处理函数。同时需要能够展示出抠图效果。 依赖与环境配置 尝试在前端接入并运行onnx。 在前端运行onnx依赖于onnxruntime-web这个包&#xff0c;这个包可以在浏览器进行模型推…

day25-XML

1.xml 1.1概述【理解】 万维网联盟(W3C) 万维网联盟(W3C)创建于1994年&#xff0c;又称W3C理事会。1994年10月在麻省理工学院计算机科学实验室成立。 建立者&#xff1a; Tim Berners-Lee (蒂姆伯纳斯李)。 是Web技术领域最具权威和影响力的国际中立性技术标准机构。 到目前为…

前端从零到一开发vscode插件并发布到插件市场

前端从零到一开发vscode插件并发布到插件市场 背景目标成果展示一条龙实现过程安装插件脚手架和工具创建项目运行调试打包第一次打包前的必要操作 发布第一次发布前账号准备注册Azure DevOps发布账号-获取token注册vscode开发者账号终端登录vsce 发布方式2-手动上传插件 进阶开…

SQL Server 拆分逗号分隔的字段为多条数据

文章目录 引言I 拆分逗号分隔的字段为多条数据1.1 使用`CROSS APPLY `拆分逗号分隔的字段为多条数据1.2 利用CHARINDEX 实现把逗号隔开的字符串拆分成行II 多列转行,逗号分隔(字段拼接/字段分割)1.1 多列转行,逗号分隔2.2 int字段类型的多行数据合并(字段拼接)2.3 SQLserver查询…

揭秘数字货币:比特币背后的技术逻辑

随着科技的飞速发展,数字货币作为一种新兴的经济形态,已经逐渐走入我们的视野。其中,比特币无疑是这一领域的佼佼者。那么,比特币背后的技术逻辑究竟是什么呢?本文将为您揭开这一神秘面纱。 一、区块链技术:比特币的基石 比特币的核心技术就是区块链(Blockchain)。区块…

K210视觉识别模块学习笔记1:第一个串口程序_程序烧录与开机启动

今日开始学习K210视觉识别模块:简单的认识与串口程序 既然K210作为一个视觉识别外设模块来使用&#xff0c;我认为第一个程序 就没必要学点灯之类的了&#xff0c;直接学习串口如何配置开始为妥&#xff0c;毕竟后面都要用到..... 在研究过程中也发现K210程序的烧录与启动也与…