首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pthread_mutex_lock块但__lock =0

pthread_mutex_lock块但__lock =0
EN

Stack Overflow用户
提问于 2014-03-10 09:07:51
回答 1查看 1.4K关注 0票数 3

我正在编写一个多线程程序,并陷入死锁。

当其他线程处于休眠状态时,其中一个线程阻塞(cond_wait)

因此,我进入ctrl+c进入gdb终端。

代码语言:javascript
复制
(gdb) info thread
  5 Thread 0x1c6ff4a0 (LWP 723)  __pthread_cond_wait (cond=0x420c50, mutex=0x420c34)
at pthread_cond_wait.c:156
  3 Thread 0x1bcf34a0 (LWP 721)  __pthread_cond_wait (cond=0x41a530, mutex=0x41a514)
at pthread_cond_wait.c:156
* 1 Thread 0x1b2c9720 (LWP 716)  __lll_lock_wait (futex=0x1be08240, private=0)
at ../nptl/sysdeps/unix/sysv/linux/lowlevellock.c:46
(gdb) bt
#0  __lll_lock_wait (futex=0x1be08240, private=0)
at ../nptl/sysdeps/unix/sysv/linux/lowlevellock.c:46
#1  0x1afa1540 in __pthread_mutex_lock (mutex=0x1be08240) at pthread_mutex_lock.c:61
#2  0x1abb7984 in readerWait (FrameInfo=0x1be08240, sem=0x1aad4000)
at CamIPCSource.cpp:282
......

我可以看到这个线程在CamIPCSource.cpp:282被阻塞了

但是当我转换到第二帧并打印互斥对象时

代码语言:javascript
复制
(gdb) frame 2
#2  0x1abb7984 in readerWait (FrameInfo=0x1be08240, sem=0x1aad4000)
at CamIPCSource.cpp:282
(gdb) p FrameInfo->m_Reader
$1 = {__data = {__lock = 0, __count = 0, __owner = 0, __kind = 0, __nusers = 0, {
  __spins = 0, __list = {__next = 0x0}}}, __size = '\000' <repeats 23 times>,
__align = 0}

这不奇怪吗?非块互斥体上的块?

当我让gdb继续运行时,程序成功地获得了锁。

我的问题:我还能做什么来知道为什么非块互斥体上的线程块呢?

环境:由mipsel-linux-gnu-g++-4.4编译,运行在mips上(libp线程-2.11.3)

下面是线程阻塞的代码段(CamIPCSource.cpp):

代码语言:javascript
复制
277 int readerWait(frame_info_t* FrameInfo, sem_t* sem) {
278     int ret;
279
280     if (FrameInfo == NULL || sem == NULL)   return -1;
281
282     pthread_mutex_lock(&FrameInfo->m_Reader);
283     /*while ((ret = pthread_mutex_trylock(&FrameInfo->m_Reader)) != 0) {
284         if (ret == EBUSY)
285             fprintf(stderr, "-");
286         else {
287             _err("pthread_mutex_trylock:(%s)\n", strerror(ret));
288             return -1;
289         }                                                                                              
290     }*/
291                                                                                            292     FrameInfo->ReaderCount++;
293     if (FrameInfo->ReaderCount == 1) {
294         if (sem_wait(sem) != 0) {
295             _err("sem_wait:(%s)\n", strerror(errno));
296             FrameInfo->ReaderCount--;
297             if ((ret = pthread_mutex_unlock(&FrameInfo->m_Reader)) != 0);
298                 _err("pthread_mutex_unlock:(%s)\n", strerror(ret));
299             return -1;
300         }
301      }
302     if ((ret = pthread_mutex_unlock(&FrameInfo->m_Reader)) != 0)
303         _err("pthread_mutex_unlock:(%s)\n", strerror(ret));
304
305     return 0;
306 }

顺便说一下,我在第283~290行尝试用pthread_mutex_lock替换pthread_mutex_trylock

而且它对某些"-“输出的效果也很好:

下面是ReaderSignal函数(ReaderWait/ReaderSignal是访问这个互斥对象的唯一两个函数)

代码语言:javascript
复制
339 int readerSignal(frame_info_t* FrameInfo, sem_t* sem) {
340     int ret;
341
342     if (FrameInfo == NULL || sem == NULL)   return -1; 
343
344     pthread_mutex_lock(&FrameInfo->m_Reader);
345     /*while ((ret = pthread_mutex_trylock(&FrameInfo->m_Reader)) != 0) {
346         if (ret == EBUSY)
347             fprintf(stderr, "-");
348         else {
349             _err("pthread_mutex_trylock:(%s)\n", strerror(ret));
350             return -1;
351         }
352     }*/
353     FrameInfo->ReaderCount--;
354     if (FrameInfo->ReaderCount == 0) {
355         if (sem_post(sem) != 0) {
356             _err("sem_post:(%s)\n", strerror(errno));
357             FrameInfo->ReaderCount++;
358             if ((ret = pthread_mutex_unlock(&FrameInfo->m_Reader)) != 0)
359                 _err("pthread_mutex_unlock:(%s)\n", strerror(ret));
360             return -1;
361         }
362
363     }
364     if ((ret = pthread_mutex_unlock(&FrameInfo->m_Reader)) != 0)
365         _err("pthread_mutex_unlock:(%s)\n", strerror(ret));
366
367     return 0;
368 }
EN

回答 1

Stack Overflow用户

发布于 2014-03-15 05:23:29

使用GDB调试多线程程序通常很困难。最好使用设计用于处理多线程问题的工具。我强烈建议您看一看Hel差市:

http://valgrind.org/docs/manual/hg-manual.html

在那一页中:"Helgrind是一个用于检测C、C++和Fortran程序中使用POSIX线程线程基元的同步错误的Val差事工具。“

它将提供关于潜在的竞赛条件,死锁等的信息,真的很棒。它救了我不止一次。

祝好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22295941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档