0

我有一个使用 pthreads 的 C 应用程序。

两个线程(比如 A 和 B)之间存在锁争用,其中 A 先获得锁,而 B 正在等待锁,一旦 A 完成并释放锁,B 仍然没有得到它,一段时间后 A 获得再次锁定(A 确实在循环中获取和释放)。
如果我将我的进程附加到 gdb 并在线程 A 放弃锁定并手动继续线程 B 后暂停线程 A,然后它会获取它并执行所需的操作。

对我来说,这看起来不像是死锁。什么可能阻止线程 B 获得锁?任何帮助是极大的赞赏。

示例代码:

线程 A:

while (true)  
{  
    lock.acquire(lock)  
    // Do stuff  
    lock.release(lock)  
    // Do more stuff  
}  

线程 B:

lock.acquire(lock)  
// Do some stuff  
lock.release(lock)  
4

2 回答 2

3

看起来您的算法遭受饥饿,您应该排队访问锁,请参阅

pthreads:快速重新锁定导致的线程饥饿

或者

公平临界区 (Linux)

作为对评论的回答,什么是互斥锁(pthread 库)

互斥锁是一个锁(来自 Pthread 库),它保证以下三件事:

原子性- 锁定互斥锁是一种原子操作,这意味着线程库向您保证,如果您锁定了一个互斥锁,则没有其他线程可以同时成功锁定该互斥锁。

奇点- 如果一个线程设法锁定了一个互斥锁,则可以确保在原始线程释放锁之前没有其他线程能够锁定同一个互斥锁。

非忙等待- 如果线程 A 尝试锁定已被线程 B 锁定的互斥体,则线程 A 将被挂起(并且不会消耗任何 CPU 资源),直到线程 B 释放锁为止。当线程 B 解锁互斥锁时,线程 A 将唤醒并继续执行,互斥锁被它锁定。

它不保证公平。

如果您仍然对某种读者作家公平感兴趣pthread_rwlock_rdlock: 允许有利于作家而不是读者,以避免作家饥饿。

于 2013-02-06T19:19:58.607 回答
0

另一种可能性是您的锁已在 A 线程上声明,从而阻止锁/释放完全释放(锁计数线程保持过高)。

饥饿是另一种很大的可能性,但是您的问题指出“一段时间后A再次获得锁定”表明超过几微秒:),这应该可以防止饥饿。

您是否有可能从 A 返回或使用 continue 语句,从而保持锁定?

于 2013-02-06T20:15:12.350 回答