曾经有一段时间我不是很清楚在c++下面,为什么创建一个thread只需要继承一下、然后重写一下run函数就可以了。因为根据我的了解,thread函数指针是不能指向类函数的。那thread类又是怎么实现的,后来有机会思考了一下,发现thread类其实是用static函数完成了,整个代码使用了一些小trick而已。
#include <iostream>
using namespace std;
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <time.h>
typedef void*(*func)(void* arg);
class thread{
public:
pthread_t td;
int stop_flag;
void* arg;
public:
thread(void* arg) {
this->stop_flag = 0;
this->arg = arg;
pthread_create(&td, NULL, &thread::process, this);
}
virtual ~thread() {
pthread_join(td, NULL);
}
void stop() {
this->stop_flag = 1;
}
int stop_status() {
return this->stop_flag;
}
static void* process(void* t){
thread* thd = (thread*) t;
thd->run();
return NULL;
}
virtual void run() {
return;
}
};
通过代码,我们可以看到,其实pthread_create的时候,函数指针指向了静态函数process。那怎么将process函数和thread类绑定在一起,原因就在这个this指针。等到process函数真正执行的时候,通过run这个虚函数,执行的代码其实是用户自定义的run函数代码。
class run_thread: public thread{
public:
run_thread(void* arg):thread(arg){}
~run_thread(){}
void run() {
while(!stop_status()){
printf("%d\n", 1);
sleep(1);
}
}
};
有了process静态函数和this指针这两个trick,所以我们编写thread的时候,只需要继承和改写一下run函数就可以了重新launch一个thread了。
int
main(int argc, char* arg[]){
run_thread r(0);
sleep(5);
r.stop();
return 0;
}
代码内容虽然简单,但是很能说明问题。其实很多设计模式也好,软件架构也好,都可以用很简洁的代码说清楚的。同时,能否从复杂的代码中提炼出软件本质,这也是对自己软件架构能力的一种考验。