线程封装

Linux下原始的API使用起来不方便,为了便于使用,尝试封装线程相关API。

看了《Linux多线程服务端编程》,陈硕是基于对象来封装的,使用了boost::bind来创建函数对象,把函数对象作为线程运行的函数。我这次尝试面向对象的封装,创建一个线程基类,子类继承这个基类,实现线程运行的主体函数即可。基类如下:

class BaseThread
{
public:
    BaseThread(const std::string& name);
    virtual ~BaseThread();
     void Run();
    void Join();
    static void* ThreadProxy(void* argument);
protected:
    virtual void DoTask() = 0;

private:
    void Initilization();
    bool initilized_;
    bool started_;
    bool joined_;
    pthread_t pthreadId_;
    pid_t tid_;
    std::string name_;

};

变量中包含了线程的名字、id(整数)、线程标识符、是否启动、初始化等。纯虚函数DoTask即为线程运行的主体函数,在子类实现这个函数即可。

静态函数ThreadProxy是线程创建后执行的入口。因为线程创建API

int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,
(void*)(*start_rtn)(void*),void *arg);

start_rtn是线程创建后执行的函数,因为静态函数有this指针,不能作为线程的入口函数。解决办法1、使用全局函数。这样就难以访问类的private和protected成员。2、友元函数。3、静态函数。
我使用了静态函数的方法。

来看一下实现

BaseThread::BaseThread(const std::string& name)
    :initilized_(false),
    started_(false),
    joined_(false),
    pthreadId_(0),
    tid_(pid_t(0)),
    name_(name)
{}
BaseThread::~BaseThread()
{
    if(initilized_ && started_ && !joined_)
        pthread_detach(pthreadId_);
}
void BaseThread::Run()
{
    assert(!started_);
    started_=true;
    //create the thread
    pthread_create(&pthreadId_,
        NULL,
        BaseThread::ThreadProxy,
        this);

}
void BaseThread::Join()
{
    assert(started_);
    assert(!joined_);
    pthread_join(pthreadId_, NULL);
}

/*staitc function used to call the real Task
*/
void* BaseThread::ThreadProxy(void* argument) 
{
    BaseThread* thread=static_cast<BaseThread*>(argument);
    thread->Initilization();
    thread->started_=true;
    thread->DoTask();
    return static_cast<void*> (0);

}

void BaseThread::Initilization() //must be called by the new thread
{
    tid_=static_cast<pid_t>(::syscall(SYS_gettid));
    initilized_=true;
}

在实现时,在Run中创建线程并执行线程函数,这里把this指针作为参数是为了方便在ThreadEntry中可以调用BaseThread类的其他成员。

在析构函数中,如果类析构时,线程已经运行且没有join,就分离它。

这样一个基本的封装就算完成了。关于线程的同步,参考muduo网络库做了封装。

下面写了几个测试:都是关于生产者消费者模型的,可以参考这里
1、生产者和消费者作为独立的类存在,在main函数中调度生产者类和消费者类。
这样实现,要求生产者和消费者同步的话,需要全局同步变量。实现参考这里:
https://github.com/KangRoger/ThreadLib/blob/master/test/ConsumerAndProductor/ConsumerAndProductor.cpp

2、生产者、消费者作为成员变量而存在,包含在类ConsumerAndProductor中。这时同步变量都作为生产者/消费者的私有变量,他们使用的互斥量和条件变量应该为同一个,可以使用指针或引用。
实现参考这里:
https://github.com/KangRoger/ThreadLib/blob/master/test/ConsumerAndProductor/ConsumerAndProductor2.cpp

线程生命周期管理还存在问题,后续完善。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值