Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4067136
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: LINUX

2011-11-16 19:38:53

多线程在网络编程中作用重大,由于创建/销毁线程、线程间通信的开销小,目前很多网络服务器都是用多线程(线程池)的模式对外提供服务。linux上开发多线程程序多使用pthread库,本文主要讨论使用C++封装pthread库时可能出现的问题。

 

封装pthread库主要有两种思路,第一种是简单的封装接口,如下所示:

 

  1. class simple_thread_t {
  2. public:
  3.     int start(void (*task)(void *), void *argp)
  4.     {
  5.         // do something else
  6.         pthread_create(&_tid, NULL, task, argp);
  7.     }
  8.     int join()
  9.     {
  10.         // do something else
  11.         pthread_join(_tid, NULL);
  12.     }
  13.     int detach()
  14.     {
  15.         pthread_detach(_tid);
  16.     }
  17.     // some other interfaces
  18. private:
  19.     pthread_t _tid;
  20. };


simple_thread_t只是简单的封装了pthread库的接口,但需要创建线程时,跟使用pthread库一样,需要先实现好线程例程函数,然后传递给start,线程执行时需要依赖的数据可以通过参数传递。

 

第二种封装方式则是在内部做了参数传递的工作,充分利用C++继承的特性,如下代码。

  1. class common_thread_t {
  2. public:
  3.     int start()
  4.     {
  5.          // do something else
  6.         pthread_create(&_tid, NULL, _process, (void *)this);
  7.     }
  8.     int join()
  9.     {
  10.         // do something else
  11.         pthread_join(_tid, NULL);
  12.     }
  13.     int detach()
  14.     {
  15.         pthread_detach(_tid);
  16.     }
  17.     // some other interfaces
  18.     virtual void run() = 0;
  19. private:
  20.     pthread_t _tid;
  21.     static void *_process(void *argp)
  22.     {
  23.         common_thread_t *thread = (common_thread_t*)argp;
  24.         thread->run();
  25.     }
  26. };

 

用户要创建线程,只需继承common_thread_t,并实现run接口即可,用户可以在子类中定义额外的数据以供run接口使用,在实现子类后,创建子类实例并调用start即可创建线程。

 

在使用common_thread_t时,有个限制,在线程没有正式运行之前,common_thread_t的对象不能销毁,否则会出现pure virtual function called的错误 因为在线程执行例程中需要调用run方法,而如果此时对象已销毁,则会找不到对应的虚函数。这个限制使得在需要创建需要detach线程时,new出来的common_thread_t对象,没有合适的时机来delete,因为不知道detach后的线程何时结束


2011年11月22日补充:
为了解决堆上创建线程释放的问题,可以使用boost::shared_ptr,让thread的run函数thread对象的的shared_ptr,使得在线程函数执行的过程中thread对象一直不会释放,等其线程函数执行完后才会被释放。

实现参考: (作者:陈硕)


阅读(4676) | 评论(3) | 转发(2) |
给主人留下些什么吧!~~

GFree_Wind2011-11-18 11:19:02

zyd_cu: process主要是为了实现继承的方式创建线程... 如果采用第一种方式实现是可以按你说的这说的这么做的........
这个跟第一个是有区别的。
第一个方式,线程的启动函数,是传入的参数,那个函数指针。
而这个方式,线程的启动函数,仍然是虚函数,可以继承的。

zyd_cu2011-11-18 09:52:15

GFree_Wind: 关于delete,我说说我的想法啊——好久没有碰C++,也许想错了。

为什么要有_process这个函数呢,能不能直接
int start(void *argp)
    {
         // do some.....
process主要是为了实现继承的方式创建线程... 如果采用第一种方式实现是可以按你说的这说的这么做的...

GFree_Wind2011-11-17 19:01:53

关于delete,我说说我的想法啊——好久没有碰C++,也许想错了。

为什么要有_process这个函数呢,能不能直接
int start(void *argp)
    {
         // do something else
        pthread_create(&_tid, NULL, run, argp);
    }
呢?
这样在start返回以后,就可以delete了。


很久没用C++了,不知道想法对不对

如果线程需要参数的话,可以用是