tb-common-utils源码分析(2):简单线程管理
2010-09-14 16:26
501 查看
在上一篇文章中,我们研究了日志类的实现。比较简单,也比较实用。这次,我们来研究一个对线程的简单管理方案。
在分析源码之前,我们先来看一个使用线程类的例子,上代码:
在代码中,我们先声明了一个自己的类Myrunable,该类继承于Runnable。Runnable是一个纯虚类,只提供一个run方法需要由子类来实现。
然后我们创建一个CThread的实例,该类用于管理一个线程,start方法用于启动一个线程,该方法有两个参数,一个是继承至Runnable的实例,一个是要传给我们线程的参数,这里没有参数传递,先设置为NULL,join方法用于将当前线程加入等待。
可以看到,如此我们可以很方便的进行线程的创建及管理。
下面我们来看看这是如何实现的。
先看看Runnable类,这个类比较简单,是一个纯虚类,只提供一个纯虚函数:
再来看看CThread类的实现 ,这个类主要负责线程的管理,可查询线程的id,传给线程的参数等,先看看其他成员变量:
再看看主要的成员函数,start函数用于启动一个线程:
该函数并不是将一个真正的线程函数传给pthread_create,而是将hook函数传给它,这样,我们可以突破需要传递静态成员函数的限制。
在hook函数中,我们可以很清楚的看到,该函数先是设置了pid,然后调用我们类中的run函数。
通过对线程的封装,我们可以将线程面向对象化了,我们可以很方便地控制与管理线程。
在分析源码之前,我们先来看一个使用线程类的例子,上代码:
#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函数。
通过对线程的封装,我们可以将线程面向对象化了,我们可以很方便地控制与管理线程。
相关文章推荐
- tb-common-utils源码分析(3):文件和目录的基本操作
- tb-common-utils源码分析(1):CLogger
- hadoop-common源码分析之-WritableUtils
- 开源JAVA爬虫crawler4j源码分析 - 3 线程管理
- Android进程/线程管理——深入源码解读+分析
- hadoop-common源码分析之-WritableUtils
- FFmpeg源码简单分析:结构体成员管理系统-AVOption
- Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
- htmlparser源码简单分析
- jdk 源码分析(20)java NIO包简单分析
- Linux内核源码分析之调度、内核线程模型 And Centos7.2's Kernel Resource Analysis
- Hadoop0.21.0源码流程分析(3)-Task节点管理启动任务
- 一个简单的python代理服务器源码分析
- Mangos源码分析(3):简单的世界服实现
- FFmpeg源代码简单分析:结构体成员管理系统-AVOption
- AsyncLayoutInflater的简单介绍和源码分析
- 第二人生的源码分析(四十)创建多个工作线程
- CloudFoundry源码分析:Cloud Controller(1)平台信息和用户管理
- 关于一个简单的网络爬虫源码分析
- solrcloud集群启动管理过程基于源码的分析