posix thread封装

2018-07-22  本文已影响0人  大头元

在看阅读RCF源码时,学习了一下posix thread在c++下的封装。

posix_thread.hpp

#include <boost/noncopyable.hpp>
#include <pthread.h>

//被pthread执行的线程入口
extern "c" {
  void* posix_thread_function(void*arg);
}

class posix_thread: private boost::noncopyable //禁止复制资源
{
public:
  template<typename Function>
  posix_thread(Function f):join_(false){
    start_thread(new func<Function>(f));
  }

  ~posix_thread();

  void join();
private:
  friend void* posix_thread_function(void*arg);//函数中访问类的私有类型、成员
  
  //提供纯虚接口,用以运行函数
  class func_base{
  public:
      virtual ~func_base(){} //需要提供一个{}
      virtual void run() = 0;
  };

  //将不同类型的函数封装统一接口
  //直接使用bind和function也可以实现这个功能
  template<typename Function>
  class func : public func_base {
  public:
  func(Function f):f_(f){}
  virtual void run() {
    f_();
  }
  private:
  Function f_;
  };

//使用RAII方式包装指针
  struct auto_func_base_ptr {
    ~auto_func_base_ptr(){
      delete p_;
    }
    func_base *p_;
  };
  void start_thread(func_base* f);

  bool join_;
  ::pthread_t thread_;
  };

thread.cpp

posix_thread::~posix_thread() {
//如果对象管理的线程没有结束,自动detach,这样线程结束时,自动释放资源;
//在c++11中线程对象析构时joinable会导致抛出异常
  if (!join_)
    pthread_detach(thread_);
}

void posix_thread::join() {
  if (!join_) {
    ::pthread_join(thread_, 0);
    join_ = true;
  }
}

void posix_thread::start_thread(func_base* arg) {
  int err = pthread_create_pthread(&thread_, 0, posix_thread_function, arg);
  if (err != 0) {
    delete arg; //负责释放资源
    //抛出异常,create thread err
  }
}


void* posix_thread_function(void*arg) {
//友元函数
  posix_thread::auto_func_base_ptr func{
    static_cast<posix_thread::func_base*>(arg)
  };//struct 内数据成员为public,可以采用这种初始化方式
  func.p_->run();
  return 0;
} 
上一篇下一篇

猜你喜欢

热点阅读