运维开发网

Linux:如何找到持有特定锁的线程?

运维开发网 https://www.qedev.com 2020-06-07 11:00 出处:网络
我有一个在 Linux上运行的多线程程序,有时如果我对它运行gstack,有一个线程正在等待锁定很长时间(比如2-3分钟),
我有一个在 Linux上运行的多线程程序,有时如果我对它运行gstack,有一个线程正在等待锁定很长时间(比如2-3分钟),

Thread 2 (Thread 0x5e502b90 (LWP 19853)):

0 0x40000410 in __kernel_vsyscall ()

1 0x400157b9 in __lll_lock_wait () from /lib/i686/nosegneg/libpthread.so.0

2 0x40010e1d in _L_lock_981 () from /lib/i686/nosegneg/libpthread.so.0

3 0x40010d3b in pthread_mutex_lock () from /lib/i686/nosegneg/libpthread.so.0

我检查了其余的线程,没有人拿这个锁,但是,一段时间后这个线程(LWP 19853)可以成功获得这个锁.

应该存在一个已经获得此锁的线程,但我找不到它,有什么我想念的吗?

编辑:

pthread_mutex_t的定义:

typedef union

{

struct __pthread_mutex_s

{

int __lock;

unsigned int __count;

int __owner;

/* KIND must stay at this position in the structure to maintain

binary compatibility. */

int __kind;

unsigned int __nusers;

extension union

{

int __spins;

__pthread_slist_t __list;

};

} __data;

char _size[_SIZEOF_PTHREAD_MUTEX_T];

long int __align;

} pthread_mutex_t;

有一个成员“__owner”,它是现在持有互斥锁的线程的id.

2-3分钟听起来很多,但如果您的系统负载很重,则无法保证您的线程在另一个解锁互斥锁后立即唤醒.因此,在您正在查看它的那一刻,可能只有没有线程(不再)持有锁.

Linux互斥分为两个阶段.大致:

>在第一阶段,对int值进行原子CAS操作以查看是否存在

可以立即锁定互斥锁.

>如果不可能,则将具有相同int地址的futex_wait系统调用传递给内核.

然后,解锁操作包括将值更改回初始值(通常为0)并执行futex_wake系统调用.然后内核查看是否有人在同一地址上注册了futex_wait调用,并恢复调度队列中的那些线程.真正被唤醒的线程以及何时取决于不同的事物,特别是启用的调度策略.无法保证线程按照放置锁定的顺序获取锁定.

0

精彩评论

暂无评论...
验证码 换一张
取 消