如何在pthreads中获取锁定互斥锁的拥有线程的线程ID

时间:2014-08-26 07:38:43

标签: linux multithreading pthreads posix mutex

一个线程有一个类型pthread_mutex_t的互斥锁为自己锁定。另一个线程想要知道持有此锁定互斥锁的线程的线程ID。

据我所知,有两种类型的线程ID。由pthread_self()返回的POSIX / pthread线程id,以及系统调用gettid()返回的linux线程ID。这两个是独立的,没有关系,AFAIK(请纠正我,如果我错了)。

结构pthread_mutex_tint __owner中有一个字段,用于存储当前持有锁的线程的线程ID。该字段可以通过

访问
pthread_mutex_t mutex;
int tid;
tid = mutex.__data.__owner;

如此处所述 - Is it possible to determine the thread holding a mutex?

__owner字段具有linux系统线程标识(由gettid()返回)而不是POSIX / pthread线程标识(由pthread_self()返回)。< / p>

我想比较当前的预定线程是否拥有互斥锁。因此,我应该将pthread_self()__owner值进行比较。

我可以使用gettid()代替pthread_self(),但我只能使用pthread_self()。 (一些可移植性功能)。

有没有办法正确确定锁定的互斥锁的线程ID,它会返回pthread_t而不是系统线程ID?

我将不胜感激,谢谢!

此致

Yusuf Husainy。

2 个答案:

答案 0 :(得分:2)

1)

  

这两个是独立的,没有任何关系,AFAIK(请纠正我,如果我错了)。

这是正确的。来自man pthread_self

  

pthread_self()返回的线程ID与   通过调用gettid(2)返回的内核线程ID。

2)

  

所以,我应该将pthread_self()与__owner值进行比较

这不正确,man pthread_self

  

线程标识符应被视为不透明:任何使用a的尝试   除了在pthreads调用之外的线程ID是不可移植的并且可以   导致未指明的结果。

3)

  

有没有办法正确确定锁定的互斥锁的线程ID,它会返回pthread_t而不是系统线程ID?

我想,不。 pthread_mutex_t包含字段int __owner;,并且没有任何包含该线程的pthread_t的pthread_owner字段:

/* Data structures for mutex handling.  The structure of the attribute
   type is not exposed on purpose.  */
typedef union
{
  struct __pthread_mutex_s
  {
    int __lock;
    unsigned int __count;
    int __owner;
#if __WORDSIZE == 64
    unsigned int __nusers;
#endif
    /* KIND must stay at this position in the structure to maintain
       binary compatibility.  */
    int __kind;
#if __WORDSIZE == 64
    int __spins;
    __pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV      1
#else
    unsigned int __nusers;
    __extension__ union
    {
      int __spins;
      __pthread_slist_t __list;
    };
#endif
  } __data;
  char __size[__SIZEOF_PTHREAD_MUTEX_T];
  long int __align;
} pthread_mutex_t;

答案 1 :(得分:0)

如何使用堆栈跟踪?例如,如果我在带有锁定互斥锁的多线程应用程序上使用pstack命令,请参阅以下内容:

# pstack <PID>

Thread 3 (Thread 0x7fb94a4f4700 (LWP 25157)):
#0  0x00000034a7e0e264 in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00000034a7e09508 in _L_lock_854 () from /lib64/libpthread.so.0
#2  0x00000034a7e093d7 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x000000000040af63 in read_from_pbx_loop(void*) ()
#4  0x00000034a7e079d1 in start_thread () from /lib64/libpthread.so.0
#5  0x00000034a7ae88fd in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7fb949cf3700 (LWP 25158)):
#0  0x00000034a7aaca3d in nanosleep () from /lib64/libc.so.6
#1  0x00000034a7ae1be4 in usleep () from /lib64/libc.so.6
#2  0x00000000004074f0 in read_from_agent_loop(void*) ()
#3  0x00000034a7e079d1 in start_thread () from /lib64/libpthread.so.0
#4  0x00000034a7ae88fd in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7fb94a4f6720 (LWP 25156)):
#0  0x00000034a7aaca3d in nanosleep () from /lib64/libc.so.6
#1  0x00000034a7ae1be4 in usleep () from /lib64/libc.so.6
#2  0x000000000040c600 in main ()

因此,您可以获取线程的堆栈跟踪并使用一些简单的启发式检查来查看线程的堆栈跟踪的最后一步是__lll_lock_wait