您的位置:首页 > 其它

【pthread系列-11】对Pthread线程进行简单的类封装

2013-02-27 11:10 447 查看

1.封装遇到的问题

将Pthreads线程封装为抽象类,这样用户在使用线程时,只需要继承一下这个抽象类,并实现相应的接口就可以了。这样做的好处是用户可以将注意力集中在线程所要执行的逻辑上,而不需要关注创建线程、销毁线程等细节问题上。这里给出两种简单的封装方法,以供参考。
我们抽象类的名称为Thread,其中有一个成员函数run,该函数为的声明形式为:
void run() = 0;
即将该成员函数声明为纯虚函数,用户继承此类必须要实现此成员函数。Thread中还有另外一个成员函数start,该函数的声明形式为:
void start();
用户在子类中调用start方法,将启动线程,并在线程中执行run函数。
最常想到的方法就是在start方法中使用pthread_create创建一个线程,并调用run函数。如下面这样的实现:

void start()

{

int status;

status = pthread_create(_pThread,NULL,Thread::run,NULL);

if(status != 0)

err_abort(“creating thread failure”,status);

}

这样编译肯定是不能通过的,这是因为pthread_create要求的线程例程的接口形式为:
void *(*thread_routin)(void *args);
而上面代码中提供的线程例程的接口形式为:
void Thread::run()
显然不符合要求的接口。
为了能够在start中调用run函数,我们不得不采用一种迂回的方式。下面提供两种方法:一种是使用静态成员函数,另外一种是使用友元函数。
静态成员函数的作用域是全局的,而不仅仅局限于某个函数中。静态成员函数的实现方法和C语言中的普通函数类似,因此静态函数没有this指针,静态函数只能操作静态成员变量。之所以将静态函数封装到类中,在很大程度上也只是为了满足面向对象的特性之一-----封装性。

2.使用静态函数

下面是一个简单的使用静态成员函数调用类中某个函数的例子,这个例子仅仅作为一个引子:

/*

* main.cpp

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#include <iostream>

#include <pthread.h>

#include <time.h>

#include "lc_error.h"

using namespace std;

class MyThread

{

public:

void run()

{

fprintf(stdout,"I'm a little tired.Sleep for a while.\n");

fflush(stdout);

sleep(5);

}

static void * thread_proxy_func(void * args)

{

MyThread * pMyThread = static_cast<MyThread *>(args);

pMyThread->run();

return NULL;

}

virtual ~MyThread(){}

};

int main(int argc,char *argv[])

{

MyThread t;

pthread_t thread;

int status;

status = pthread_create(&thread,NULL,MyThread::thread_proxy_func,(void *)&t);

if(status != 0)

err_abort("creating thread error...\n",status);

status = pthread_join(thread,NULL);

if(status != 0)

err_abort("joining thread...\n",status);

return 0;

}

需要特别注意的是mian函数中使用pthread_create的执行例程为MyThread类中的线程代理函数thread_proxy_func,在此函数中在调用run函数,这样就顺利的迂回到了run函数。基于这种方法,我们可以用静态函数来封装一个简单的抽象类,以下为封装的代码,由三个文件构成:Thread.h(类的声明文件),Thread.cpp(类的实现文件),main.cpp(测试文件):

/*

* Thread.h

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#ifndef THREAD_H_

#define THREAD_H_

#include "lc_error.h"

#include <pthread.h>

class Thread

{

public:

Thread();

~Thread();

virtual void run() = 0;

void start();

void wait();

private:
static void * thread_proxy_func(void *args);

pthread_t * _pThread;

};

#endif /* THREAD_H_ */


/*

* Thread.cpp

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#include "Thread.h"

Thread::Thread()

{

_pThread = (pthread_t *)malloc(sizeof(pthread_t));

if(NULL == _pThread)

error_abort("malloc error...\n");

}

Thread::~Thread()

{

if(NULL != _pThread)

delete _pThread;

}

void Thread::start()

{

int status;

status = pthread_create(_pThread,NULL,thread_proxy_func,this);

if(status != 0)

err_abort("creating thread...\n",status);

}

void * Thread::thread_proxy_func(void *args)

{

Thread * pThread = static_cast<Thread *>(args);

pThread->run();

return NULL;

}

void Thread::wait()

{

int status;

status = pthread_join(*_pThread,NULL);

if(status != 0)

err_abort("joining thread error...\n",status);

}


3.使用友元函数
友元函数的作用和静态函数相同,都起到一个代理的作用。需要将对象的指针作为参数传递给这个友元函数,然后在友元函数中调用run函数。代码如下,
由三个文件构成:Thread.h(类的声明文件),Thread.cpp(类的实现文件),main.cpp(测试文件):

/*

* Thread.h

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#ifndef THREAD_H_

#define THREAD_H_

#include "lc_error.h"

#include <pthread.h>

class Thread

{

public:

friend void * proxy_thread_func(void * args);

Thread();

virtual ~Thread();

void start();

virtual void run(void) = 0;

void wait();

private:

pthread_t * _thread;

};

void * proxy_thread_func(void * args);

#endif /* THREAD_H_ */


/*

* Thread.cpp

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#include "Thread.h"

void * proxy_thread_func(void * args)

{

Thread * _thread = static_cast<Thread *>(args);

_thread->run();

return NULL;

}

Thread::Thread()

{

_thread = (pthread_t * )malloc(sizeof(pthread_t));

if(NULL == _thread)

error_abort("malloc failure...\n");

}

Thread::~Thread()

{

if(_thread != NULL)

delete _thread;

}

void Thread::start()

{

int status;

status = pthread_create(_thread,NULL,proxy_thread_func,this);

if(status != 0)

err_abort("creating thread error...\n",status);

}

void Thread::wait()

{

int status;

status = pthread_join(*_thread,NULL);

if(status != 0)

err_abort("joing thread...\n",status);

}

/*

* main.c

*

*  Created on: Jul 24, 2012

*      Author: lichao

*/

#include "Thread.h"

#include <iostream>

#include <time.h>

using namespace std;

class MyThread:public Thread

{

public:

void run()

{

cout<<"I'm a littile tired. Sleep for a while..."<<endl;

sleep(5);

}

virtual ~MyThread(){}

};

int main(int argc,char *argv[])

{

MyThread t;

t.start();

t.wait();

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: