免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2309 | 回复: 9
打印 上一主题 下一主题

[请教]这段代码怎么死锁了?谢谢!~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-22 11:51 |只看该作者 |倒序浏览
写的一个生产者,消费者模型的线程间buf,死锁了一次。不是可重现的,很偶然才出现。
void ThreadBuffer::pushFreeBuf(int sub)
{
        bool bwait=false;
        _freeMutex->acquire();
        if (_freeList.empty())
                bwait=true;
        _freeList.push(sub);
        _freeMutex->release();
        if (bwait)
                _freeCond->signal();
}

int ThreadBuffer::popFreeBuf()
{
        int sub;
        _freeMutex->acquire();
        while (_freeList.empty())
        {
                _freeCond->wait();
        }
         _freeList.pop(sub);
         _freeMutex->release();
         return sub;
}
使用的时候一个线程调用popFreeBuf取buf,另外的线程调用pushFreeBuf向里面放buf,freelist是一个队列,freeMutex和freeCond是ACE的同步变量,就是mutex和condition。
死锁的时候看,freelist不是空的,有数据,但是调用popFreeBuf的线程堵在了_freeCond->wait() 这一句,从这个现象看应该是其他线程发的信号给丢了。但是看代码,应该不可能丢啊,各位老大帮我看看,谢谢了!~

论坛徽章:
0
2 [报告]
发表于 2007-08-22 12:31 |只看该作者
btw:没用过ACE


  1. void ThreadBuffer::pushFreeBuf(int sub)
  2. {
  3.       
  4.         _freeMutex->acquire();
  5.         if (_freeList.empty()){
  6.                
  7.                 _freeCond->signal();
  8.          }else{
  9.                 _freeList.push(sub);
  10.         
  11.          }
  12.         _freeMutex->release();
  13.       
  14. }

  15. int ThreadBuffer::popFreeBuf()
  16. {
  17.         int sub;
  18.         while (_freeList.empty())
  19.         {
  20.                 _freeCond->wait();
  21.         }
  22.         _freeMutex->acquire();
  23.          _freeList.pop(sub);
  24.          _freeMutex->release();
  25.          return sub;
  26. }
复制代码

[ 本帖最后由 FreeGnu 于 2007-8-22 13:43 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2007-08-22 12:47 |只看该作者
为什么不会丢呢?
而且你的bwait每次都重新赋false
一旦丢了一个以后,就再也不会signal了
wait会一直等着

原帖由 wxp19831104 于 2007-8-22 11:51 发表
写的一个生产者,消费者模型的线程间buf,死锁了一次。不是可重现的,很偶然才出现。
void ThreadBuffer::pushFreeBuf(int sub)
{
        bool bwait=false;
        _freeMutex->acquire();
        if (_freeList.empty())
...

论坛徽章:
0
4 [报告]
发表于 2007-08-22 13:00 |只看该作者

回复 #1 wxp19831104 的帖子

你wait时,_freeMutex被锁住了。这时候,如果ThreadBuffer::pushFreeBuf(int sub)再加锁_freeMutex时,必须等待, 所以就执行不了signal。 都这样了,不死锁才怪。

论坛徽章:
0
5 [报告]
发表于 2007-08-22 13:01 |只看该作者
condition变量会自动释放掉锁的

btw 我也没有用过ACE

原帖由 web_surf 于 2007-8-22 13:00 发表
你wait时,_freeMutex被锁住了。这时候,如果ThreadBuffer::pushFreeBuf(int sub)再加锁_freeMutex时,必须等待, 所以就执行不了signal。 都这样了,不死锁才怪。

论坛徽章:
0
6 [报告]
发表于 2007-08-22 13:13 |只看该作者
在特定的顺序下signal会被丢弃,比如调用次序如下
    producer                            comsumer
1  release
2                                            acquire
3                                            is empty?
4  signal
5                                            wait

第4步的signal因为没有thread在waiting所以丢失,而comsumer仍然认为队列为空

论坛徽章:
0
7 [报告]
发表于 2007-08-22 16:06 |只看该作者

回复 #3 ypxing 的帖子

问题是第一个signal不会丢啊。bwait是个局部变量,初始化为false,他在mutex同步的区域里访问freeList,如果是empty就肯定会发一个signal,这个信号不会丢的啊。。

论坛徽章:
0
8 [报告]
发表于 2007-08-22 16:08 |只看该作者

回复 #5 ypxing 的帖子

condition在wait的时候,是会自动释放锁的。
ACE的condition和Mutex就是简单的封装了pthread的同步函数。

论坛徽章:
0
9 [报告]
发表于 2007-08-22 16:10 |只看该作者

回复 #6 tinywind 的帖子

如果producer release了,那么就不会是empty了啊。。所以consumer应该不会wait,直接取数据的啊。。。

论坛徽章:
0
10 [报告]
发表于 2007-08-22 16:20 |只看该作者

回复 #9 wxp19831104 的帖子

想错了,删掉:wink:

[ 本帖最后由 tinywind 于 2007-8-22 16:26 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP