在看阅读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;
}
网友评论