我有一个使用pthreads的C应用程序。
在两个线程(比如A和B)之间存在锁争用,其中A在B等待锁定时首先获得锁定,一旦A完成并释放锁定,B仍然不能获得它并且在一段时间之后A获得再次锁定(A确实获取并在循环中释放)。 如果我将我的进程附加到gdb并在它放弃锁定并在线程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)
看起来您的算法遭受饥饿困扰,您应该对锁定进行排队,请参阅
pthreads: thread starvation caused by quick re-locking
要么
作为评论的答案,什么是互斥(pthread库)
互斥锁是一个锁(来自Pthread库),它保证以下三件事:
原子性 - 锁定互斥锁是一种原子操作,这意味着线程库会向您保证,如果您锁定互斥锁,则其他线程无法同时锁定该互斥锁。
奇点 - 如果线程设法锁定互斥锁,则确保在原始线程释放锁之前,没有其他线程能够锁定相同的互斥锁。
非忙等待 - 如果threadA尝试锁定由threadB锁定的互斥锁,则threadA将被挂起(并且不会消耗任何CPU资源),直到threadB释放锁。当threadB解锁互斥锁时,线程A将被唤醒并继续执行,互斥锁被锁定。
它不保证公平。
如果你仍然对pthread_rwlock_rdlock
的读者作家公平感兴趣:允许作家优先于读者以避免作家饥饿。
另一种可能性是你的锁先前已在A线程中声明锁定,防止锁定/释放完全释放(锁定计数线程保持太高)。
饥饿是另一个强大的可能性,但你的问题是“过了一会儿A再次获得锁定”,表明超过几微秒:),这应该可以防止饥饿。
您是否有可能从A返回或使用continue语句,从而保持锁定?