pthread由于是C 库,所以在C++里使用pthread时会出现一些很莫名的bug
bug 1: c++ 类对于pthread的封装
习惯了面向对象的思想和Java Thread的使用,转到C++时就想着要是也有一个Thread的基类就好了,它封装了phtread启动线程的细节,同时对外开放了一个虚函数run()。这个虚函数就是自定义线程的实际工作任务的执行入口。
基类同时还有一个start函数,用于启动线程.
这样等到想利用线程做某些工作的时候,只要继承这个Thread基类,实现虚函数run(),把想要完成的工作放到run()中就行了。
下面给出了基类的定义:
class CCThread {
public:
CCThread ();
virtual ~CCThread () = 0;
void start();
virtual void run() = 0 ;
private:
/* data */
pthread_t pid ;
};
最开始的实现:
CCThread::CCThread(){}
CCThread::~CCThread(){}
void CCThread::start(){
pthread_create(&pid,NULL,run,NULL);
}
但编译器提示pthread_create函数第3个参数不匹配
google了一下,原来第3个参数接收的函数的签名必须为:void* func(void* )
更改了定义:
class CCThread {
public:
CCThread ();
virtual ~CCThread () = 0;
void start();
virtual void* run(void* param) = 0 ;
private:
/* data */
pthread_t pid ;
};
但编译器还是提示pthread_create函数第3个参数不匹配
??不是改过了吗?
再google了一下,原来类成员没法直接作为pthread_create的第3个参数
按照网上的做法,
1. 把run函数变为static成员,但这样的话就没法声明为virtual成员了
2. 只能定义一个额外的threadFunc函数作为pthread_create的第3个参数,同时把this指针传给它:
定义:.h
class CCThread {
public:
CCThread ();
virtual ~CCThread () = 0;
void start();
virtual void run() = 0 ;
private:
/* data */
pthread_t pid ;
};
实现:.cc
void* threadFunc(void* param)
{
CCThread* ccthread = (CCThread*)param ;
ccthread->run();
return 0;
}
CCThread::CCThread(){}
CCThread::~CCThread(){}
void CCThread::start(){
pthread_create(&pid,NULL,threadFunc,this);
}
编译通过!!!!
bug 2: c库就是c库,跟C++库混在一起时就会抽疯:
为了检验自己的CCThread基类,就实现了一个子类EchoThread.
定义如下:
class EchoThread :public CCThread{
public:
EchoThread(int id)
{
_id = id ;
}
~EchoThread()
{}
void run(){
while(1){
cout<<"current running thread:"<<_id<
}
private:
/* data */
int _id ;
};
int main(){
for(int i=1;i<=10;i++)
{
EchoThread* et = new EchoThread(i); // 必须使用new机制,不能是EchoThread et(i) ,想要多态,就用New
et->start();
}
while(1) // 不要小瞧这个无用的while循环,没了它main线程就会很快结束,EchoThread线程也会随之结束。不信,你试试
;
return 0;
}
编译通过,可执行时就扯蛋了,
部分结果如下:
current running thread:1
current running thread:current running thread:13
current running thread:3
current running thread:current running thread:83current running thread:
current running thread:9
current running thread:9
current running thread:current running thread:current running thread:7
current running thread:7
current running thread:7
current running thread:2
current running thread:2
current running thread:2
current running thread:2
current running thread:2
current running thread:2
current running thread:2
为什么呀????????
最后发现,不用cout,而用printf就正常了。
void run(){
while(1){
printf("current running thread:%d \n",_id);
}
}
C++就是有那么多让人蛋疼的地方!!!!