免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: inet_addr
打印 上一主题 下一主题

[c++]类和线程怎么结合{有码) [复制链接]

论坛徽章:
0
11 [报告]
发表于 2012-06-21 15:30 |只看该作者
回复 10# inet_addr


    静态函数只是个面向库的接口而已,是private不对外的。里面调用线程类的实际工作函数
  1. class thread
  2. {
  3. public:
  4.      virtual void run() = 0;
  5. private:
  6.      static void *thread_proc(thread *thrd)
  7.     {
  8.         thrd->run();
  9.     }
  10. };

  11. class my_thread : public thread
  12. {
  13. public:
  14.     void run()
  15.     {
  16.         // 这才是实际干事情的地方
  17.     }
  18. }

复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2012-06-21 15:38 |只看该作者
尔等根本体会不到写C++的乐趣

  1. #include <my_pthread.h>
  2. #include <stdio.h>

  3. struct foo
  4. {
  5.     int n;
  6.     void *test(void *arg)
  7.     {
  8.         for(int i = 0; i < 10; ++i)
  9.             printf("%d \n", ++n);
  10.                 return NULL;
  11.     }
  12. };

  13. int main()
  14. {
  15.     foo f;
  16.     pthread_t id;
  17.     my_pthread_create(&f, &id, NULL, &foo::test, NULL);
  18.     pthread_join(id, NULL);
  19.     return 0;
  20. }
复制代码
以下为 my_pthread.h

  1. #ifndef INC_THREAD_PROXY_H_
  2. #define INC_THREAD_PROXY_H_

  3. #include <pthread.h>
  4. #include <semaphore.h>

  5. template <class T>
  6. class thread_proxy_imp
  7. {
  8. protected:
  9.     typedef struct
  10.     {
  11.         void *(T::*start_routine_)(void *);
  12.         void      *arg_;
  13.         T         *obj_;
  14.         sem_t      sem_;
  15.     } thread_param;

  16.     static void *thread_proxy_entry(void *arg)
  17.     {
  18.         thread_param *param_ptr = reinterpret_cast<thread_param *>(arg);
  19.         thread_param  param     = *param_ptr;
  20.         sem_post(&param.sem_);
  21.         return (param.obj_->*param.start_routine_)(param.arg_);
  22.     }

  23. public:
  24.     int create(
  25.         T                    *obj,
  26.         pthread_t            *thread,
  27.         const pthread_attr_t *attr,
  28.         void            *(T::*start_routine) (void *),
  29.         void                 *arg)
  30.     {
  31.         int rt;
  32.         thread_param param = {start_routine, arg, obj};
  33.         
  34.         sem_init(&param.sem_, 0, 0);
  35.         rt = pthread_create(thread,
  36.                             attr,
  37.                                                         thread_proxy_imp::thread_proxy_entry,
  38.                                                         reinterpret_cast<void *>(&param));
  39.         if(rt == 0) sem_wait(&param.sem_);
  40.         sem_destroy(&param.sem_);
  41.         return rt;
  42.     }
  43. };


  44. template<class T>
  45. int my_pthread_create(
  46.         T                    *obj,
  47.     pthread_t            *thread,
  48.     const pthread_attr_t *attr,
  49.     void            *(T::*start_routine) (void *),
  50.     void                 *arg)
  51. {
  52.     return thread_proxy_imp<T>().create(obj, thread, attr, start_routine, arg);
  53. }

  54. #endif



复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2012-06-21 15:56 |只看该作者
nilgod 发表于 2012-06-21 15:39
目前看起来感觉使用lambda似乎看起来更优秀。


pthread_pthread 如何结合lambda用,请教。。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
14 [报告]
发表于 2012-06-21 16:18 |只看该作者
回复 16# nilgod

是吗,还是第一次有人这么批评我的。

那我等着,你有货拿出来遛遛,别太监了。
   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
15 [报告]
发表于 2012-06-21 16:23 |只看该作者
回复 19# nilgod

没事。我最喜欢看到真实的意见了。
不过,你说一塌糊涂和烂,要具体的指明烂之所在。
这个不影响你装系统吧。
   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
16 [报告]
发表于 2012-06-21 16:33 |只看该作者
nigod哑炮了?真是个二货。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
17 [报告]
发表于 2012-06-21 16:44 |只看该作者
晕啊,我不好在哪里啊,就凭你感觉?!真是个二货没错。。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
18 [报告]
发表于 2012-06-21 16:46 |只看该作者
回复 24# nilgod


    我原本等着你指出我的不足,好好切磋一下,
结果发现不靠谱。

你说 “第一是感觉,第二是你整个就不好。",
这是什么狗屁理由啊

论坛徽章:
0
19 [报告]
发表于 2012-06-21 16:50 |只看该作者
关注点不一样,封装自然不同。

只关注任务本身,不关心线程,像群雄逐鹿中原那么封装比较好。但是要对线程进行操作,自然是nilgod的封装比较好。

有一点是互通的,那就是用静态函数进行转接。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
20 [报告]
发表于 2012-06-21 17:01 |只看该作者
本帖最后由 群雄逐鹿中原 于 2012-06-21 17:06 编辑

好吧,为了让某些网友服气点,我再多罗嗦两点

1. 逐鹿在13楼的封装,很简单,
   就是针对楼主的需求,对于类里的线程函数,
   只要加上类对象 f 就行了,除此之外没有别的功能。
    my_pthread_create(&f, &id, NULL, &foo::test, NULL);
   几乎和原生的pthread_create函数一样用法,简单上手。
   
2. 某网友在22楼的代码,class和thread结合,
   里面有一个极其典型的bug,
   就是构造函数启动线程,线程调用虚函数。
   构造函数里调用:
      Start(process, stackSize, isSuspended);
   Start线程后,用virtual
      virtual DWORD Run();
   
   这个bug相当典型,并且是一般情况下不出现,偶尔出一下会要命,
   不注意的人极难找到。
   
为什么逐鹿如此肯定这个bug呢?
为什么逐鹿在13楼用小清新的封装办法呢?
你不被这样的事情折磨几次,不会明白的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP