您的位置:首页 > 其它

tb-common-utils源码分析(2):简单线程管理

2010-09-14 16:26 501 查看
在上一篇文章中,我们研究了日志类的实现。比较简单,也比较实用。这次,我们来研究一个对线程的简单管理方案。

在分析源码之前,我们先来看一个使用线程类的例子,上代码:

#include <stdio.h>
// 引用头文件
#include <tbsys.h>
using namespace tbsys;
// 写我们继承的线程类
class Myrunable : public Runnable {
// 此处是我们的线程函数
void run(CThread *thread, void *arg) {
printf("thread run/n");
}
};
int main() {

// 创建我们的线程类
Myrunable test;

// 创建线程管理实例
CThread thread;
// 启动线程
thread.start(&test, NULL);

// 等待线程退出
thread.join();

return 0;
}


在代码中,我们先声明了一个自己的类Myrunable,该类继承于Runnable。Runnable是一个纯虚类,只提供一个run方法需要由子类来实现。

然后我们创建一个CThread的实例,该类用于管理一个线程,start方法用于启动一个线程,该方法有两个参数,一个是继承至Runnable的实例,一个是要传给我们线程的参数,这里没有参数传递,先设置为NULL,join方法用于将当前线程加入等待。

可以看到,如此我们可以很方便的进行线程的创建及管理。

下面我们来看看这是如何实现的。

先看看Runnable类,这个类比较简单,是一个纯虚类,只提供一个纯虚函数:

class Runnable {
public:
/*
* 析构
*/
virtual ~Runnable() {
}
/**
* 运行入口函数
*/
virtual void run(CThread *thread, void *arg) = 0;
};


再来看看CThread类的实现 ,这个类主要负责线程的管理,可查询线程的id,传给线程的参数等,先看看其他成员变量:

private:
pthread_t tid;      // pthread_self() id
int pid;            // 线程的进程ID
Runnable *runnable;
void *args;


再看看主要的成员函数,start函数用于启动一个线程:

void start(Runnable *r, void *a) {
runnable = r;
args = a;
// 创建线程,线程函数是hook,并将自己传给该函数
pthread_create(&tid, NULL, CThread::hook, this);
}


该函数并不是将一个真正的线程函数传给pthread_create,而是将hook函数传给它,这样,我们可以突破需要传递静态成员函数的限制。

static void *hook(void *arg) {
// 得到线程类
CThread *thread = (CThread*) arg;
thread->pid = gettid();
if (thread->getRunnable()) {
// 调用线程运行类
thread->getRunnable()->run(thread, thread->getArgs());
}
return (void*) NULL;
}


在hook函数中,我们可以很清楚的看到,该函数先是设置了pid,然后调用我们类中的run函数。

通过对线程的封装,我们可以将线程面向对象化了,我们可以很方便地控制与管理线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: