线程原生库的简单封装(二)

下面实现了一个通用的线程封装类Thread<T>
提供start()(创建线程)、join()(等待线程结束)、detach()(分离线程)、stop()(标记线程停止状态)等接口,覆盖了线程的基本操作需求。

#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include <pthread.h>
#include <iostream>
#include <string>
#include <functional>
namespace ThreadModule
{
    template<typename T>
    using func_t = std::function<void(T)>;//将 std::function<void()> 这个类型起一个别名 func_t, 用于保存传入T参数,返回值为void的函数(可调用对象)

    template<typename T>
    class Thread
    {
    private:
        void Excute()
        {
            _func(_data);
            return;
        }
    public:
        Thread(func_t<T> func, T data, const std::string &name="none-name")
        : _func(func), _data(data), _threadname(name), _stop(true)
        {}
        // static void *threadroutine(void* args)//类成员函数,形参是有this指针的,所以在前面要加static
        // {
        //     _func(_data);
        //     return nullptr;
        // }
        static void *threadroutine(void* args)//类成员函数,形参是有this指针的,所以在前面要加static
        {
            Thread<T> *self = static_cast<Thread<T>*>(args);
            self->Excute();
            return nullptr;
        }
        std::string name() const
        {
            return _threadname;
        }
        bool start()
        {
            int n = pthread_create(&_tid, nullptr, threadroutine, this);
            if(n != 0)//创建线程失败
            {
                return false;
            }
            else//创建线程成功
            {
                _stop = false;
                return true;
            }
        }
        void detach()
        {
            if(!_stop)
            {
                pthread_detach(_tid);
            }
        }
        void join()
        {
            if(!_stop)
            {
                pthread_join(_tid, nullptr);
            }
        }
        void stop()
        {
            _stop = true;
        }
        ~Thread(){}
    private:
        pthread_t _tid;
        std::string _threadname;
        T _data;
        func_t<T> _func;
        bool _stop;
    };
}


#endif // __THREAD_HPP__

细节一:

原生线程被使用时,类内成员函数被使用时,要加static,去掉this指针。
因为调用pthread_creare时传入的函数有格式要求只能是形如void *function(void* args),返回值必须是void类型,传入参数只有一个,是void类型。
但是在类中,作为成员函数,这个void *threadroutine(void* args)函数的第一个参数实际上是this指针(Thread* const this),用来传递自己属于哪个对象的。
所以这里要加上static,变成一个类的专属,这时没有this指针,符合pthread_creare时传入的函数的格式要求。

细节二:

static void *threadroutine(void* args)
{
    _func(_data);//这个函数无法直接用_data
    return nullptr;
}

这里是行不通的,加了static已经无this指针了,直接用_data是不行的(原因:函数是在公共代码区,调用时不知道是哪个对象调用,需要this指针指明,但是这里由于加了static,没有this指针)。

解决方法:可以间接的用其他成员函数去调用_data。

private:
    void Excute()
    {
        _func(_data);
        return;
    }
public:
    // static void *threadroutine(void* args)
    // {
    //     _func(_data);
    //     return nullptr;
    // }
    static void *threadroutine(void* args)
    {
        Thread<T> *self = static_cast<Thread<T>*>(args);//这时args里面要传一个类对象,利用这个对象去调用Excute从而访问_data
        self->Excute();
        return nullptr;
    }

这种写法是 C++ 中使用类成员函数作为线程入口的标准范式,既满足了pthread_create对函数格式的要求(静态函数,无隐含this),又通过显式传递对象指针实现了对类内部资源的访问。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子13

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值