【问题标题】:How to get thread id of owning thread for a locked mutex in pthreads如何为 pthreads 中的锁定互斥锁获取拥有线程的线程 ID
【发布时间】:2014-10-19 11:04:12
【问题描述】:

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

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

结构体pthread_mutex_t,int __owner中有一个字段存储了当前持有锁的线程的线程id。这个字段可以被访问,

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

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

__owner 字段具有 linux 系统线程 ID(将由 gettid() 返回)而不是 POSIX/pthread 线程 ID(将由 pthread_self() 返回)。

我想比较当前调度的线程是否拥有互斥锁。所以,我应该将pthread_self()__owner 值进行比较。

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

有什么方法可以正确确定锁定的互斥锁的线程 ID,它会返回 pthread_t 而不是系统线程 ID?

我将不胜感激,谢谢!

问候,

优素福·侯赛尼。

【问题讨论】:

  • 既然你在技术上是一个不透明的对象(pthread_mutex_t)里面闲逛,担心可移植性问题似乎有点晚了?我想你需要做的是构造一个__owner 值到pthread_self() 的映射,每个pthread 可以在启动时将自己添加到该映射中。 (该映射需要由互斥锁保护,当 pthread “注册”自身时,可以从中提取 __owner 值。)
  • Is it possible to determine the thread holding a mutex? 的可能重复项请问您的问题与您链接的问题有何不同?
  • @alk,我明白,我的问题有所不同,因为我想知道一种方法来获取 pthread_t 类型的线程 id,而不是系统 TID 类型。链接的问题没有对此给出任何解决方案。
  • 所以您同意这两个问题是相同的。我怀疑你得到了你的问题的答案,就像另一个问题的答案一样,没有答案。对于后一种解决方法提出了建议。
  • 只需编写您想要的代码。我建议使用单独的互斥锁来保护所有者变量。

标签: linux multithreading pthreads posix mutex


【解决方案1】:

为此使用堆栈跟踪怎么样?例如,如果我在具有锁定互斥锁的多线程应用程序上使用 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

【讨论】:

    【解决方案2】:

    1)

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

    没错。来自man pthread_self

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

    2)

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

    这是不正确的,man pthread_self

    线程标识符应该被认为是不透明的:任何尝试使用 pthreads 调用以外的线程 ID 是不可移植的,并且可以 导致未指定的结果。

    3)

    有什么方法可以正确确定锁定的互斥锁的线程 id,它会返回 pthread_t 而不是系统线程 id?

    我猜,没有。 pthread_mutex_t 具有字段int __owner;,并且没有像pthread_owner 这样包含线程pthread_t 的字段:

    /* 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;
    

    【讨论】:

      猜你喜欢
      • 2010-12-29
      • 2020-12-07
      • 2012-12-25
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 2023-03-21
      • 2021-11-07
      • 1970-01-01
      相关资源
      最近更新 更多