【问题标题】:Issue with Lock Ordering or Scheduling锁定排序或调度问题
【发布时间】:2013-01-22 02:30:38
【问题描述】:

我有一个使用 pthread 的 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)  

【问题讨论】:

  • 请贴一些代码。描述严重不足。
  • 你熟悉饥饿这个概念吗?
  • 你用的是什么类型的“锁”?
  • 我在这里使用 pthread_mutex_lock

标签: c locking pthreads scheduling deadlock


【解决方案1】:

看起来您的算法遇到了饥饿问题,您应该排队访问锁,请参阅

pthreads: thread starvation caused by quick re-locking

Fair critical section (Linux)

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

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

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

Singularity - 如果一个线程设法锁定了一个互斥体,则可以确保 没有其他线程能够锁定同一个互斥锁,直到原来的 线程释放锁。

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

不保证公平。

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

【讨论】:

  • mutex 不是在内部使用 mutex->waiters 吗?
  • @keeda:它会在解锁时唤醒所有等待的线程,但那些唤醒的线程不一定会立即安排 - 例如,如果您只有一个核心,那么通常允许您的原始线程在它被抢占之前完成它的时间片。 Pthreads 互斥锁非常轻量级,并不是为了“公平”而设计的。
  • 感谢 Caf,我想通了。我正在尝试使用诸如保证公平的队列之类的东西来实现公平的 FIFO 锁。试图实现 [link]en.wikipedia.org/wiki/Ticket_lock
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多