下面采用两种风格实现thread类
一.基于对象的风格
#ifndef _THREAD_H
#define _THREAD_H
#include <pthread.h>
class thread {
public:
thread();
virtual ~thread();
public:
void start();
void join();
virtual void run() = 0;
private:
static void* thread_routine(void* arg);
pthread_t tid_;
};
#endif
.cpp
#include "thread.h"
#include <iostream>
#include <assert.h>
using namespace std;
thread::thread()
{
cout<<"thread ..."<<endl;
}
thread::~thread()
{
cout<<"~thread ..."<<endl;
}
void thread::start()
{
int ret = pthread_create(&tid_, NULL, thread_routine, this);
assert(ret != -1);
}
void thread::join()
{
pthread_join(tid_, NULL);
}
//@param : pointer to derive class
void* thread::thread_routine(void* arg)
{
thread* th = static_cast<thread*>(arg);
//static member function cannot directly call none member function
th->run();
return NULL;
}
#include "thread.h"
#include <unistd.h>
#include <iostream>
using namespace std;
class test_thread : public thread {
public:
test_thread(int count) : count_(count) {
cout<<"test_thread ..."<<endl;
}
~test_thread() {
cout<<"~test_thread ..."<<endl;
}
private:
void run() {
while(count_--){
cout<<"this is a test ..."<<endl;
}
}
private:
int count_;
};
int main()
{
test_thread t(5);
t.start();
t.join();
return 0;
}
我们线程类中要使用pthread_create(),想要用run()函数作为线程运行函数。run()是普通的成员函数,隐含的第一个参数是this指针,调用的时候遵循thiscall约定,某一个寄存器会保存this指针,而prhtread_create()的线程运行函数需要调用普通入口函数。
这个问题有一下几种解决方案:
1.使用一个全局函数,但是这会向外界暴露这个函数。
2.类内部使用static修饰线程运行函数,将this指针作为pthread_create()第四个参数传递。
派生类对象调用t.start(),t调用成员函数,隐含了了一个t的this指针,调用的start()其实调用的是基类的start(),start()中pthread_create()又把this指针传给线程运行函数,所以是吧派生类对象又传到了thread_routinue(),然后在该函数中使用基类指针指向派生类对象,基类指针调用派生类实现的虚函数,这就是虚函数的多态,同时也是虚函数回调应用函数。
上面是一个派生类调用基类start()方法,基类中又回调了派生类的run()方法。静态成员函数不能调用非静态成员,不过有时我们为了实现可以传递this指针,通过this指针调用即可。
线程对象的生命周期 与 线程的生命周期是不一样的。
在栈上分配的对象生命周期是有局部作用域决定的,动态创建的对象可以使用delete销毁。
二:基于对象的编程风格
示例:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using namespace std;
class foo {
public:
void member_func(double d, int i, int j) {
cout<<d<<endl;
cout<<i<<endl;
cout<<j<<endl;
}
};
int main()
{
foo f;
//boost::function<void(int)> fp = boost::bind(&foo::member_func, &f, 0.5, _1, 10); //_1相当于占位符,&f是传指针,相当于(&foo)->member_func()
boost::function<void(int)> fp = boost::bind(&foo::member_func, boost::ref(f), 0.5, _1, 10); //boost::ref指明它是一个引用,详单与foo.member_func()
fp(100); //输出0.5, 100, 10
return 0;
}
基于对象的thread类参见我的这篇文章:http://blog.csdn.net/freeelinux/article/details/52916620
三:两者区别