【发布时间】:2013-02-03 12:38:02
【问题描述】:
假设我在调用pthread_mutex_lock() 时有多个线程阻塞。当互斥锁可用时,调用pthread_mutex_lock() 的第一个线程是否获得锁?也就是说,是否按 FIFO 顺序调用 pthread_mutex_lock()?如果不是,它们的顺序是什么(如果有的话)?谢谢!
【问题讨论】:
标签: c multithreading pthreads
假设我在调用pthread_mutex_lock() 时有多个线程阻塞。当互斥锁可用时,调用pthread_mutex_lock() 的第一个线程是否获得锁?也就是说,是否按 FIFO 顺序调用 pthread_mutex_lock()?如果不是,它们的顺序是什么(如果有的话)?谢谢!
【问题讨论】:
标签: c multithreading pthreads
当互斥体可用时,调用
pthread_mutex_lock()的第一个线程是否获得锁?
没有。其中一个等待的线程获得了锁,但不确定是哪一个。
先进先出顺序?
FIFO 互斥体已经是一种模式。见Implementing a FIFO mutex in pthreads
【讨论】:
pthread_mutex_lock 的线程,当它可用时第一个获得锁,以此类推后续线程。猜猜我正在实施我自己的。谢谢。
pthread_mutex_lock 的线程在可用时第一个获得锁” - 是的,这正是 FIFO 互斥锁的含义关于。
“如果调用pthread_mutex_unlock()时mutex引用的mutex对象上有线程阻塞,导致mutex可用,调度策略将决定哪个线程获取mutex。”
除此之外,POSIX 标准并未指定您的问题的答案。根据实现的选择,它可能是随机的,也可能是 FIFO 或 LIFO 或任何其他顺序。
【讨论】:
FIFO 排序可能是效率最低的互斥唤醒顺序。只有真正糟糕的实现才会使用它。最近运行的线程可能能够在没有上下文切换的情况下再次运行,并且最近运行的线程,其更多的数据和代码将在缓存中处于热状态。合理的实现会尝试将互斥锁分配给大多数时间最近持有它的线程。
考虑执行此操作的两个线程:
现在想象两个线程在单核 CPU 上运行此代码。应该清楚的是,FIFO 互斥行为会导致每次上下文切换都“调整一些数据”——这是最坏的结果。
当然,合理的实现通常确实对公平性有所帮助。我们不希望一个线程没有任何进展。但这很难证明 FIFO 实现的合理性!
【讨论】: