【问题标题】:check if a pthread lock variable is locked [duplicate]检查pthread锁变量是否被锁定[重复]
【发布时间】:2014-09-05 21:18:24
【问题描述】:

我想知道一个 pthread 锁变量是否被锁定。 一种简单的方法是使用trylock,如下所示

pthread_mutex_t lockVar;
if(pthread_mutex_trylock(&lockVar) == 0)
{
    //lock was successful
    pthread_mutex_unlock(&lockVar);
}
else
{
    //someone else holds the lock
}

如何在不获取锁的情况下做同样的事情?

【问题讨论】:

  • 我认为您要查找的词是“mutex”。
  • 它就在那里,在代码中 ;-)

标签: c pthreads mutex


【解决方案1】:

当您同时执行多个执行时,就没有“同时性”的概念。事件不能及时给出全局顺序,除非发生显式同步。在语言中没有可观察到的属性可以观察到任何一般的排序。

具体来说,“那里的互斥锁是否被锁定”的问题是没有意义的。它没有你可以采取行动的答案。无论虚构的答案是什么,互斥锁的状态都可以立即改变。对于“是的,它已锁定”(它可能同时解锁)或“不,它已解锁”(它可能在您到达那里之前被锁定)之类的答案,您无能为力。

唯一你可以对互斥体做的事情是尝试锁定它。您要么失败,因此知道它已被锁定,要么您成功并因此知道它不是,现在您拥有了锁定。

【讨论】:

  • 感谢您的解释。 Whatever the fictitious answer is, the state of the mutex can change right after。所以呢?。 It has no answer upon which you can act。为什么?
  • @arunmoezhi:唯一有意义的答案是程序中是否存在不变量,例如一旦解锁互斥锁,另一个线程就不可能再次锁定它。在这种情况下,一旦通过 trylock 获得互斥锁,您就可以保持它处于锁定状态,因为这样做不会阻塞任何其他线程的前进进程。
  • 我认为“那里的互斥锁是否被锁定”这个问题在并发设置中是有意义的,从某种意义上说,部分顺序足以保证正确性
  • @arunmoezhi:如果你不能接受给出的答案,我认为你需要解释你想对答案做什么,以便 Kerrek 或我解决你对任何剩余的困惑他的回答。
  • @KerrekSB:肯定有。如果不存在其他线程,则该函数不正确。还有很多其他方法可以证明它是错误的。这实际上是一个有趣的话题,因为很多人错误地认为你不能证明 trylock 的错误实现是错误的,但你可以。这个话题是在向 glibc 添加锁省略时出现的,并且在 POSIX 与 C11 内存模型的对齐过程中再次出现。 :-)
【解决方案2】:

不管你想对结果做什么,你现在做的方式是唯一的方法。您不能简单地查询互斥锁是否被锁定而不锁定它。如果您想要一个无需修改即可查询状态的同步原语,则可以使用 POSIX 信号量。二进制信号量可以用作锁(尽管它缺少所有者的概念,如果您需要递归锁定,这可能对您来说是个问题)并且sem_getvalue 可以确定信号量是否被“锁定”在一个瞬间

至于你问的问题是否有意义,Kerrek 已经告诉过你通常没有。以下是一些可能的,您可以从负面或正面结果中收集到的最有用的信息:

  • 否定:

    • 如果您知道锁开始被锁定,并且一旦解锁就不会再次被锁定,这告诉您操作已经完成。在这里,trylock-and-unlock 方法会阻止多个线程执行此操作,因为它会破坏“一旦解锁就不再锁定”的不变量。
    • 可能表明值得在不持有锁的情况下准备数据,您可以稍后通过 trylock/unlock 在准备好数据后仅在短暂的时间间隔内进行应用。但是,当然,您必须为以后锁定时情况发生变化的情况做好准备。
  • 正面:

    • 如果您知道在您的线程执行允许锁持有者继续进行的进一步操作之前,锁一旦被占用就不会被解锁,这会为您提供锁持有者已到达的信息。
  • 也许其他人...

但在大多数情况下,“互斥锁是否被锁定?”不是一个有用的问题。

【讨论】:

  • 关于你的第一点“操作已经完成”的事情是,你不能仅仅依赖这种技术,因为你可能永远不会观察到完成方式。因此,您已经必须编写单独的代码路径来处理一般情况。那时您很可能只需删除特殊情况代码路径...
  • @KerrekSB:如果您不需要同步内存(例如,您可能只需要对文件描述符的某些操作进行排序),只需知道操作完成就足够了,无需额外同步.我同意这通常是错误的,我一直试图说服 OP 相信这一点,但我认为一些有限的特殊情况示例,您 可以 使用结果可能有助于帮助 OP 意识到在大多数情况下你不能
  • 很抱歉,我仍然不明白你的意思。互斥变量以unlocked 状态开头。然后它变为locked,unlocked,locked... 假设观察者想要读取互斥变量的状态(不一定是当前状态)。假设他将值读取为locked。但是当他/她读到它的时候,这个值可能已经变成了unlocked。但是他/她读取的值是过去的某个有效状态。如果他读取的值不是过去或现在的值,那么我就有麻烦了。但只要它是历史的一部分,我就可以。
  • @arunmoezhi:关键是没有同步就没有历史。没有“过去”。 “过去”意味着时间顺序,但没有时间顺序(除非您同步)。
  • 这给出了我要问的概念。 en.wikipedia.org/wiki/…
猜你喜欢
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多