首页 > 系统相关 >【Linux】线程ID、线程封装(详解)

【Linux】线程ID、线程封装(详解)

时间:2024-10-24 10:49:39浏览次数:6  
标签:name void Linux 线程 func pthread ID

线程ID

认识线程ID

怎么查看一个线程的ID呢?                                                                                                             

线程库 NPTL 提供了 pthread_ self 函数, 可以获得线程自身的 ID;
不知道的可以看下面文章中的pthread_self()即可;【Linux】线程基本概念,线程控制-CSDN博客

void *Run(void *args)
{
    cout << (char *)args << " TID: " << pthread_self() << endl;
    sleep(5);
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, Run, (void *)"thread -1");
    cout << "main thread TID :" << pthread_self() << endl;
    sleep(5);
    return 0;
}

运行结果:

pthread_ create 函数会产生一个线程 ID, 存放在第一个参数指向的地址中。
该线程 ID 和前面说的线程 ID (LWP)不是一回事。从图中可以很明显的看到LWP不等于TID;

  • LWP:属于进程调度的范畴。 因为线程是轻量级进程, 是操作系统调度器的最小单位, 所以需要一个数值来唯一表示该线程;
  • TID:pthread_t 类型的线程 ID, 本质就是一个进程地址空间上的一个地址。

给用户提供的线程ID,不是内核中的LWP,而是自己维护的一个唯一值,这个维护是pthread库维护的;

将TID转换成十六进程打印出来,我们可以知道ID其实是一个地址;

理解库

一个进程在创建多线程之前,首先我们在执行pthread_create之前,这个库被加载到内存并映射到进程的地址空间;

库如何对线程进程管理呢?先描述,在组织

所谓的先描述就是在库中创建描述线程相关结构体字段属性;在组织就是"数组";

所以未来我们只要找到线程控制块的地址,就能访问到线程的所有的属性

Linux线程 = pthread库中线程的属性集 + LWP(1:1);

所以tid本质就是线程属性集合的起始虚拟地址;

封装线程

首先我们先写一下封装后的线程,可以调用函数,这个函数有功能:

下面我们在根据start(),stop(),join()来写;

start()

start():在start中我们要有用pthread_create来创建一个线程;其中线程的执行函数routine里面要执行的任务我们用回调函数来写:

定义:

线程要执行的方法:

using func_t = function<void()>;

类似于 typedef function<void()> func_t ;

typedef void (*func_t)(const string &name); // 函数指针类型

注意:因为routine是类内的成员方法,所以routine隐含了一个参数:this指针(Thread * this),这样就不满足void *(*__start_routine)(void *)了,可以直接把routine加上static,这样routine属于类,就不属于对象了,参数就没有this指针了;但是这样这里就不能直接调用类内的回调函数了,所以我们就要把当前对象传进来;

Thread *self = static_cast<Thread *>(args);                                                                                  int n = ::pthread_create(&_tid, nullptr, routine,this);

stop()

stop():在stop中我们要先判断是否是运行状态,如果是就会进行stop,而stop的做法就是pthread_cancel(取消)当前进程;最后更改当前的状态;

join()

join():pthread_join其实就是线程等待;

 加锁

主要函数完成后就是对细节内容进行修改即可;

完整代码:

  1. #pragma once
    
    #include <iostream>
    #include <string>
    #include <pthread.h>
    #include <functional>
    #include <unistd.h>
    #include <cstring>
    #include <cerrno>
    using namespace std;
    
    // 线程要执行的方法
    // using func_t = function<void()>;
    // 就类似于 typedef function<void()> func_t ;
    
    class ThreadData
    {
    public:
        ThreadData(const string &name,pthread_mutex_t*lock):_name(name),_lock(lock)
        {}
    public:
        string _name;
        pthread_mutex_t*_lock;
    };
    
    typedef void (*func_t)(ThreadData *td); // 函数指针类型
    
    class Thread
    {
    public:
        void Excute()
        {
            _isrunning = true;
            _func(_td);
        }
    
    public:
        Thread(const string &name, func_t func,ThreadData*td) : _name(name), _func(func),_td(td)
        {
        }
        ~Thread()
        {
        }
        string status()
        {
            if (_isrunning)
                return "running";
            return "sleep";
        }
        static void *routine(void *args)
        {
            Thread *self = static_cast<Thread *>(args);
            self->Excute();
            return nullptr;
        }
        bool start()
        {
            int n = ::pthread_create(&_tid, nullptr, routine,this); //::强度了使用标准库中的方法
            if (n == 0)
            {
                return true;
            }
            return false;
        }
        void stop()
        {
            if (_isrunning)
            {
                pthread_cancel(_tid);
                _isrunning = false;
            }
        }
        void join()
        {
            if (!_isrunning)
            {
                pthread_join(_tid, nullptr);
            }
        }
        string Name()
        {
            return _name;
        }
    
    private:
        pthread_t _tid;
        string _name;
        bool _isrunning;
        func_t _func; // 线程要执行的回调函数
        ThreadData *_td;
    };
    

以上就是线程ID和封装线程的全部内容,希望有所帮助!!!

标签:name,void,Linux,线程,func,pthread,ID
From: https://blog.csdn.net/weixin_74116463/article/details/143176536

相关文章

  • ACDC电源模块BAG5-15W系列 双输出电源 BOSHIDA博士达
    ACDC电源模块BAG5-15W系列双输出电源BOSHIDA博士达产品具有以下特点:宽输入电压范围85-265VAC,适用于不同地区的电源电压标准。高效率、高可靠性,保证稳定而可靠的电源输出。空载功耗低,节约能源,减少不必要的电能损耗。隔离电压2500VAC,保证电源的安全性和稳定性。输出过压、过流......
  • Java“线程独享小金库”:揭秘 ThreadLocal 的妙用与陷阱
    前言在Java并发编程的世界里,线程间争抢资源犹如一场“抢椅子”游戏,稍有不慎就会碰撞出问题的火花。可是,想象一下,如果每个线程都有自己独享的“小金库”,再也不用担心其他线程来“顺手牵羊”,这该是多么惬意!没错,这就是ThreadLocal的魔力所在。它为每个线程量身定制独一无二的存......
  • IDEA 一键自动在Ubuntu 部署 Springboot 的 Jar包
    1.创建服务文件/etc/systemd/system/test.service[Unit]Description=测试After=syslog.target[Service]User=rootRestart=alwaysExecStart=java-jar/root/test/test.jarStandardOutput=append:/root/test/test.logStandardError=append:/root/test/test.log[Inst......
  • linux shell 脚本语言教程(超详细!)
    Shell编程详细指南什么是Shell?Shell是用户与操作系统内核之间的接口,允许用户通过命令行输入来控制操作系统。它充当命令解释器,读取用户输入的命令并执行相应的操作。Shell提供了强大的脚本编程能力,可以自动化许多任务。常见的Shell有Bash(BourneAgainShell)、Zsh(ZShell)......
  • DevExpress WinForms中文教程:Data Grid - 如何在代码中处理列?
    在本教程中,您将学习如何在分配数据源时启用或禁用自动列生成,如何手动填充列集合和访问单个列。请注意,本教程的重点是在代码中完成这些任务。显然您也可以使用网格的集成设计器对话框和VisualStudio的属性网格来做同样的事情,这将在单独的教程中进行描述。P.S:DevExpressWinForms......
  • Windows、macOS和Linux系统安装Python的指南
    在不同的操作系统上安装Python通常涉及几个简单的步骤。以下是在Windows、macOS和Linux系统上安装Python的指南:Windows系统安装Python:下载Python安装程序:访问Python官方网站 python.org。选择适合Windows的Python版本(确保下载最新稳定版)。运行安装程序:双击下载的.exe文......
  • [linux]常用指令
    命令初体验体验Linux命令的使用执行命令时,如果提示信息出现乱码,是由于编码问题导致的,执行命令修改Linux的编码即可命令1:把配置写入指定文件命令2:重新加载指定文件Linux命令格式:command[-options][parameter]command:命令名[-options]:选项,可同来......
  • [linux]快速入门
    学习目标通过学习能够掌握以下的linux操作操作系统按照应用领域的不同,操作系统可以分为几类桌面操作系统服务器操作系统移动设备操作系统嵌入式操作系统不同领域的主流操作系统桌面操作系统Windows(用户数量最多)MacOS(操作体验好,办公人士首选)Linux(用户数量少)......
  • Linux系统性能优化实战指南
    引言Linux,作为开源操作系统的代表,凭借其高效、稳定、灵活的特性,在服务器、嵌入式设备、云计算等多个领域占据主导地位。然而,随着业务的发展和系统负载的增加,Linux系统的性能优化成为运维和开发人员必须面对的重要课题。本文将从硬件资源优化、内核参数调整、文件系统优化、......
  • linux提交之6e90b6-开源之耻!
    本周合并到Linux6.12-rc4内核中的一个补丁删除了一些内核维护者,使其不再出现在官方MAINTAINERS文件中,该文件可识别所有驱动程序和子系统维护者。其中包括宏碁Aspire1EC驱动程序、CirrusLogicCLPS711XARM架构、Baikal-T1PVT硬件监控器驱动程序、LibataPATA驱动程......