【问题标题】:How can I grant ownership of a mutex to a specific thread?如何将互斥锁的所有权授予特定线程?
【发布时间】:2012-10-03 05:45:52
【问题描述】:

假设我有一个互斥锁被锁定。有无限数量的其他线程等待锁定互斥锁。当我解锁互斥锁时,将选择其中一个线程进入临界区。但是我无法控制哪一个。如果我想让特定线程进入临界区怎么办?

我很确定这不能使用 POSIX 互斥锁来完成,但是,我可以使用不同的同步对象来模拟这种行为吗?

【问题讨论】:

  • 您将获得的唯一保证是某些机制的公平性,但它们都没有您需要的功能。你不能重新设计你的算法不依赖于哪个线程先通过吗?也许如果你解释一下你在做什么,我们可以想到一些事情。
  • 这是防止死锁的方法:我在一个临界区,我即将锁定另一个临界区。但是,我知道有另一个线程锁定了后一个 CS,并试图锁定前一个 CS。为了防止死锁,我需要通知其他线程应该取消其锁定前 CS 的尝试。
  • 每个线程不能按相同的顺序获取所有的锁吗?这样就不会出现死锁问题。
  • 不,不能。顺便说一句,请在下面查看一个可行的 - 虽然不是很有效 - 解决方案。

标签: multithreading mutex critical-section


【解决方案1】:

您可以使用互斥锁、条件变量和线程 ID 来实现。

在解锁互斥锁之前,线程设置目标线程ID,广播条件变量并释放互斥锁。等待线程唤醒,锁定互斥体并检查目标线程 id 是否等于该线程 id。如果不是,则线程返回等待。

为了避免唤醒所有等待线程只是为了检查目标线程 ID 然后返回等待,对此方法的优化是为每个等待线程使用单独的条件变量。这样,信号线程将通知特定目标线程的条件变量。


另一种选择是使用发送到特定线程的信号。假设我们为此目的使用SIGRTMIN。首先,所有线程在开始时阻塞这个信号,这样信号就处于未决状态,并且在线程不等待它时不会丢失。当一个线程想要锁定互斥体时,它首先调用sigwait(),它以原子方式解除对SIGRTMIN 的阻塞并等待它或传递一个已经挂起的。一旦线程收到信号,它就可以继续并锁定互斥锁。信令线程使用pthread_kill(target_thread_id, SIGRTMIN) 唤醒特定线程。

【讨论】:

  • 是的。我已经这样做了。我担心随机让线程进入临界区并检查它是否是正确的线程的性能开销。不过目前我想不出更好的办法。
  • @MartinSustrik 我添加了另一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多