锁定排序或调度问题

问题描述 投票:0回答:2

我有一个使用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)  
c locking pthreads scheduling deadlock
2个回答
3
投票

看起来您的算法遭受饥饿困扰,您应该对锁定进行排队,请参阅

pthreads: thread starvation caused by quick re-locking

要么

Fair critical section (Linux)

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

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

原子性 - 锁定互斥锁是一种原子操作,这意味着线程库会向您保证,如果您锁定互斥锁,则其他线程无法同时锁定该互斥锁。

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

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

它不保证公平。

如果你仍然对pthread_rwlock_rdlock的读者作家公平感兴趣:允许作家优先于读者以避免作家饥饿。


0
投票

另一种可能性是你的锁先前已在A线程中声明锁定,防止锁定/释放完全释放(锁定计数线程保持太高)。

饥饿是另一个强大的可能性,但你的问题是“过了一会儿A再次获得锁定”,表明超过几微秒:),这应该可以防止饥饿。

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

© www.soinside.com 2019 - 2024. All rights reserved.