免费注册 查看新帖 |

Chinaunix

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

[C++] 帮我看下这段代码是否有问题,总是死锁 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-05-18 16:39 |只看该作者 |倒序浏览
本帖最后由 jd808 于 2015-05-18 16:40 编辑
  1. int BaseTEngine::CallConnList(std::tr1::function<int(Conn *,Conn *,const char *)> f,Conn * ActConn,const char *command)
  2. {
  3.         Conn *pNext= NULL, *pcon= NULL;

  4.         ConnList* m_UserList = g_pServer->GetUserList();
  5.         for (int i=0; i<g_pServer->GetUserListCount(); i++) {
  6.                 pthread_rwlock_rdlock(&m_UserList[i].ConnListLock);
  7.                 pcon = m_UserList[i].GetHead()->GetNext();
  8.                 while (pcon != NULL) {
  9.                         pNext = pcon->GetNext();
  10.                         if(pcon->is_login==1&& pcon->fd_type==1)
  11.                                 f(pcon,ActConn,command);
  12.                         pcon = pNext;
  13.                 }

  14.                 pthread_rwlock_unlock(&m_UserList[i].ConnListLock);
  15.         }

  16.         return 0;
  17. }
复制代码
这是用户线程里的
另外一个主线程
  1. ConnList *plist = conn->GetList();
  2.         pthread_rwlock_wrlock(&plist->ConnListLock);//在用户大规模断开,并且有部分用户在大规模发送消息的时候这里出现死锁
  3.         conn->GetList()->Delete(conn);       
  4.         pthread_rwlock_unlock(&plist->ConnListLock);
复制代码
一直找不到原因,Delete里只是删除链表的一个元素而已,f(pcon,ActConn,command);这个函数也是保证绝对安全的,就是调用libevent的发送函数将消息发送出去。
也没发现有死循环的现象,一但死锁,cpu暂用为0,死循环的话应该cpu很高才对。
大虾帮忙看看。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2015-05-18 16:53 |只看该作者
读写锁,改成写优先

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2015-05-18 17:16 |只看该作者
hellioncu 发表于 2015-05-18 16:53
读写锁,改成写优先
老兄,咋改?还有,为啥要改成写优先?这是死锁,不是在等待哦。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2015-05-18 17:25 |只看该作者
jd808 发表于 2015-05-18 17:16
老兄,咋改?还有,为啥要改成写优先?这是死锁,不是在等待哦。


我猜是读太多,写饿死了,感觉就像死锁

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2015-05-18 17:59 |只看该作者
hellioncu 发表于 2015-05-18 17:25
我猜是读太多,写饿死了,感觉就像死锁

问题是cpu不高,一旦死锁,cpu即使等半个小时也是0,基本不处理数据了,感觉不太像是饿死的吧。

论坛徽章:
0
6 [报告]
发表于 2015-05-19 18:36 |只看该作者
建议看看这个进程“死锁”时的堆栈,gstack一下瞧瞧到底在等什么就了然了

论坛徽章:
0
7 [报告]
发表于 2015-05-19 18:49 |只看该作者
就是感觉这段代码有点risk

  1. ConnList *plist = conn->GetList();
  2.         pthread_rwlock_wrlock(&plist->ConnListLock);//在用户大规模断开,并且有部分用户在大规模发送消息的时候这里出现死锁
  3.         conn->GetList()->Delete(conn);   //这里delete conn会不会有问题?      
  4.         pthread_rwlock_unlock(&plist->ConnListLock);
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2015-05-19 21:14 |只看该作者
foolishx 发表于 2015-05-19 18:49
就是感觉这段代码有点risk

能否明确一下风险在哪里?

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
9 [报告]
发表于 2015-05-20 09:57 |只看该作者
把读写锁干掉,就直接上mutex,实际上读写锁的性能并没有想象中的那么好

论坛徽章:
0
10 [报告]
发表于 2015-05-22 10:05 |只看该作者
记得以前在多线程中对map进行了erase,导致了死锁,后来硬是改成了循环标记的方式,建议对delete替换测试后,测是否有死锁行为
回复 7# foolishx


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP