Linux从0到1——线程自定义封装

Linux从0到1------线程自定义封装


1. Thread.hpp


cpp 复制代码
#pragma once

#include <iostream>
#include <string>
#include <functional>

template<class T>
using func_t = std::function<void(T)>;

template<class T>
class Thread
{
public:
    Thread(func_t<T> func, const std::string &threadname, T data)
        :_tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
    {}

    static void *ThreadRoutine(void* args)	// 静态成员方法,没有this指针
    {
        Thread *ts = static_cast<Thread *>(args);

        ts->_func(ts->_data);

        return nullptr;
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if(n == 0) 
        {
            _isrunning = true;
            return true;
        }
        else return false;
    }

    bool Join()
    {
        if(!_isrunning) return false;
        int n = pthread_join(_tid, nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }

    bool IsRunning()
    {
        return _isrunning;
    }

    ~Thread()
    {}

private:
    pthread_t _tid;             // 库级别线程id
    std::string _threadname;    // 线程名
    bool _isrunning;             // 运行状态
    func_t<T> _func;               // 线程执行的回调方法
    T _data;
};
  • 需要格外注意一点,ThreadRoutine必须写成静态成员函数,因为普通成员函数会默认携带this指针,这样就会有两个参数,一个this,一个void* args。而pthread_create函数只接受只有一个参数void* args的函数。
  • ThreadRoutine写成静态成员函数后,它将无法通过隐含的this指针访问到成员变量_func。为了解决这个问题,可以将this指针显示的传给pthread_create函数的void* args参数,这样ThreadRoutine就拿到了this指针,之后再做一些变换就可以访问到_func了。

2. main.cc


  • 作文测试文件,测试封装的效果:
cpp 复制代码
#include <iostream>
#include <unistd.h>
#include <string>
#include "Thread.hpp"

std::string GetThreadName()
{
    static int number = 1;  // 声明周期随进程,且只在当前作用域有效
    char name[64];
    snprintf(name, sizeof(name), "Thread-%d", number++);
    return name;
}

void Print(int num)
{
    while(num--)
    {
        std::cout << "hello world" << std::endl;
        sleep(1);
    }
}

int main()
{
    Thread<int> t(Print, GetThreadName(), 5);
    std::cout << "is thread running?" << t.IsRunning() << std::endl;
    t.Start();
    std::cout << "is thread running?" << t.IsRunning() << std::endl;
    t.Join();
    std::cout << "Join done" << std::endl;
    return 0;
}
  • 运行结果:

相关推荐
像风一样的男人@26 分钟前
linux --防火墙
linux·运维·服务器
U-52184F6939 分钟前
C++ 实战:构建通用的层次化数据模型 (Hierarchical Data Model)
开发语言·c++
charlie1145141911 小时前
深入解构:MSVC 调试机制与 Visual Studio 调试器原理
c++·ide·windows·学习·visual studio·调试·现代c++
Trouvaille ~1 小时前
【C++篇】把混沌映射成秩序:哈希表的底层哲学与实现之道
数据结构·c++·stl·哈希算法·散列表·面向对象·基础入门
网硕互联的小客服1 小时前
Centos系统如何更改root账户用户名?需要注意什么?
linux·运维·服务器·数据库·安全
肆悟先生1 小时前
3.14 函数的参数传递
c++
lisanmengmeng1 小时前
zentao的prod环境升级(一)
linux·运维·数据库·docker·容器·禅道
wunianor1 小时前
[高并发服务器]DEBUG日志
linux·运维·服务器·c++
nbsaas-boot1 小时前
SQL Server 存储过程设计规范(事务与异常处理)
linux·数据库·设计规范
天赐学c语言2 小时前
12.19 - 买卖股票的最佳时机 && const的作用
c++·算法·leecode