免费注册 查看新帖 |

Chinaunix

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

[C++] 推荐我写的一个C++多线程程序开发库 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2007-06-20 16:29 |只看该作者
原帖由 foochow 于 2007-6-20 15:00 发表
支持一个先..
直接用ACE不就可以了?

知道有ACE的,为了自己提高下,所以找个目标

多谢上面各位的建议,这几天好好学习一下,希望不久能推出改进版!

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
22 [报告]
发表于 2007-06-20 19:11 |只看该作者
你可以参考一下网络上的"linux下通用线程池"

论坛徽章:
0
23 [报告]
发表于 2007-06-21 08:55 |只看该作者

  1. static void ThreadSafePrint(const char * szMsg)
  2. {
  3.         if(!Initted)
  4.         {
  5.                 InitLock(&LockPrint);
  6.                 Initted = true;
  7.         }
  8.         LockOn(&LockPrint);
  9. #ifdef __DEBUG__
  10.         printf(szMsg);
  11. #endif
  12.         LockOff(&LockPrint);
  13. }
复制代码


没下载你的代码,从1楼的回复中看到上面的代码。LZ可以应用一个C++编程常用的机制:"resource acquisition is initialization"。

按照这种机制,你的LockOn和LockOff两个函数应该分别做成一个类的构造函数和析构函数。这样,加锁时只需构造一个相应的局部对象。而解锁则不用你操心了,当这个对象超出作用域时会自动析构(并解锁)。这样就避免了你由于各种原因(疏忽、异常)没有调用解锁函数。

[ 本帖最后由 lgfang 于 2007-6-21 10:13 编辑 ]

论坛徽章:
0
24 [报告]
发表于 2007-06-21 09:21 |只看该作者
原帖由 lgfang 于 2007-6-21 08:55 发表
按照这种机制,你的LockOn和LockOff两个函数应该分别做成一个类的构造函数和析构函数。这样,加锁时只需构造一个相应的局部对象。而解锁则不用你操心了,当这个对象超出作用域时会自动析构(并解锁)。这样就避免了你由于各种原因(疏忽、异常)没有调用解锁函数。

谢谢。
我对你的说法的理解是:
由于不同的资源使用不同的锁,所以在构造这个特殊类的时候,我们应该重载一个将锁变量作为参数的构造函数,然后在声明这个对象时就构造一个局部对象来加锁,当局部对象退出时就自动解锁。
但是lgfang同学有没有想到会遇到这样的情况。比如函数:

  1. void PlayGame()
  2. {
  3.    LockOn(&LoginLock);
  4.    Login();
  5.    LockOff(&LoginLock);
  6.    while(haveMoney())
  7.    {
  8.         Play();
  9.        //这里可能会花费很多时间
  10.    }
  11. }
复制代码

如果按照LZ的意思,可能会将代码改造为如下的方式

  1. class Lock
  2. {
  3. LockType* Lk;
  4. public:
  5.     Lock(LockType*lk){Lk = lk;LockOn(Lk);}
  6.     ~Lock(){LockOff(Lk);}
  7. }
  8. void PlayGame()
  9. {
  10.    Lock lk(&LoginLock)
  11.    Login();
  12.    while(haveMoney())
  13.    {
  14.         Play();
  15.        //这里可能会花费很多时间
  16.    }
  17. }
复制代码

这样的话,在整个while(haveMoney())期间,lk都没有destruct掉,LoginLock是被LockOn的,其它对象的调用就会阻塞的,显然这不是我们想要的效果

[ 本帖最后由 duanjigang 于 2007-6-21 09:23 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
25 [报告]
发表于 2007-06-21 09:24 |只看该作者

  1. void PlayGame()
  2. {
  3.    {
  4.         Lock lk(&LoginLock)
  5.         Login();
  6.    }
  7.    while(haveMoney())
  8.    {
  9.         Play();
  10.        //这里可能会花费很多时间
  11.    }
  12. }
复制代码


可以这样

论坛徽章:
0
26 [报告]
发表于 2007-06-21 09:32 |只看该作者
接着上面的。
其实也可以这么改造下:

  1. void PlayGame()
  2. {
  3.    {
  4.       Lock lk(&LoginLock)
  5.       Login();
  6.    }
  7.   while(haveMoney())
  8.    {
  9.         Play();
  10.        //这里可能会花费很多时间
  11.    }
  12. }
复制代码

这样就可以及时的LockOff了,也就是destruct掉lk,但是个人感觉对于程序的可读性有些影响,不如

  1. void PlayGame()
  2. {
  3.    LockOn(&LoginLock);
  4.    Login();
  5.    LockOff(&LoginLock);
  6.    while(haveMoney())
  7.    {
  8.         Play();
  9.        //这里可能会花费很多时间
  10.    }
  11. }
复制代码
看起来一目了然些。而且感觉要求用大括号把局部对象括起来跟LockOn和LockOff要配对是一样的意思
不过你的这种思想确实不错,很感激。
顺带提一下,对于为了控制作用域而显式调用destructor的方式,如下的代码:

  1. void PlayGame()
  2. {
  3.    Lock lk(&LoginLock)
  4.    Login();
  5.    lk.Lock::~Lock();
  6.   while(haveMoney())
  7.    {
  8.         Play();
  9.        //这里可能会花费很多时间
  10.    }
  11. }
复制代码

你我估计都不会去采用吧,因为这跟显式LockOn和LockOff没区别。

[ 本帖最后由 duanjigang 于 2007-6-21 09:46 编辑 ]

论坛徽章:
0
27 [报告]
发表于 2007-06-21 09:34 |只看该作者
呵呵,还没写出来,就有人回复了

论坛徽章:
0
28 [报告]
发表于 2007-06-21 09:50 |只看该作者

  1. void PlayGame()
  2. {
  3.    {
  4.       Lock lk(&LoginLock)
  5.       Login();
  6.    }
  7.   while(haveMoney())
  8.    {
  9.         Play();
  10.        //这里可能会花费很多时间
  11.    }
  12. }
复制代码

这样就可以及时的LockOff了,也就是destruct掉lk,但是感觉对于程序的可读性有些影响,个人感觉不如显式调用LockOn和LockOff来的明白些。


1,在实际项目中,是安全性、健壮性重要还是可读性重要?
    我已经不止一次目睹了因为忘记释放资源导致程序出问题。而其中很多应该都是可以避免的。

2,具体到你举的例子,对可读性有影响是因为你的代码本身的问题,和RAII机制无关。既然LoginLock是只为login准备的,为什么不把代码改成这样:

  1. bool login(){
  2.     Lock lk(&LoginLock);
  3.     // login
  4. }

  5. void PlayGame()
  6. {
  7.   if ( ! login()) { // ...
  8.   }

  9.   while(haveMoney())
  10.    {
  11.         Play();
  12.        //这里可能会花费很多时间
  13.    }
  14. }

复制代码

论坛徽章:
0
29 [报告]
发表于 2007-06-21 09:55 |只看该作者
顺带提一下,对于为了控制作用域而显式调用destructor的方式,如下的代码:


  1. void PlayGame()
  2. {
  3.    Lock lk(&LoginLock)
  4.    Login();
  5.    lk.Lock::~Lock();
  6.   while(haveMoney())
  7.    {
  8.         Play();
  9.        //这里可能会花费很多时间
  10.    }
  11. }
复制代码

你我估计都不会去采用吧,因为这跟显式LockOn和LockOff没区别。


确实有需要的话,你可以写一个解锁的成员函数。

论坛徽章:
0
30 [报告]
发表于 2007-06-21 09:59 |只看该作者
感觉要求用大括号把局部对象括起来跟LockOn和LockOff要配对是一样的意思

不一样。括号不匹配,编译器会报错。没调用LockOff,编译器是无从知道的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP