在互斥锁解锁时取消阻止定时接收

Posted

技术标签:

【中文标题】在互斥锁解锁时取消阻止定时接收【英文标题】:Unblock from timed receive on mutex unlock 【发布时间】:2016-01-21 11:13:35 【问题描述】:

我有一个线程尝试使用定时接收函数从消息队列中读取内容。线程还有一个互斥锁,它作为它何时需要退出的指示器(例如,应用程序已关闭):最初互斥锁被锁定,当它被解锁时(在其他地方),线程需要停止。

我想以这样一种方式进行定时接收,即当互斥锁解锁时它也会解除阻塞。因此,当我们被要求停止时,我们会立即执行此操作,而无需等待定时接收超时。

在 Windows 中,我可以使用重叠的 IO 和 WaitForMultipleObjects() 来实现。命名管道上的重叠读取返回给我一个对象,然后我同时等待该对象和互斥体。

在 POSIX 中有没有办法做到这一点?

【问题讨论】:

你能不能只在队列中发布一些消息来唤醒线程并让它注意到一些“终止”布尔值?在非平凡的操作系统上,如果线程不需要在应用程序终止之前关闭,你不应该尝试明确地终止它,除非有这样做的压倒一切的要求。 @MartinJames 是的,这实际上可以工作。 C 不是 C++ 不是 C!选择一种语言。 @Olaf 什么?这适用于任何一个。 请自行告知。 C 和 C++ 是不同的语言。如果您使用 C++ C-style 进行编码,那么 1) 并不意味着相同的语义,并且 2) 是非常糟糕的编码风格。其他方式类似。如果有人告诉你不同,他显然不会足够好地了解至少一种语言。 【参考方案1】:

有很多方法。可能最简单的方法是在线程应该停止时使用设置为true 的布尔值。用互斥锁保护布尔值并让线程定期检查它。

更好的解决方案是使用原子布尔值。最有可能的是,您使用的平台具有它们,来自 C++-11,作为编译器内在函数,或其他方式。

【讨论】:

如果只有一个写入器和多个读取器,那么互斥锁甚至都不是必需的。 @Ctx POSIX 有一个explicit requirement,当内存位置在或可能在另一个线程中访问时,它不能在一个线程中修改。因此,您肯定需要互斥锁或某种形式的原子操作。 我的问题不是如何定期检查互斥锁,而是如何在互斥锁解锁后立即退出定时接收,即使这发生在超时之前。假设您有一个超时时间为 1 小时的定时接收。 5 分钟内互斥锁解锁。我希望定时接收在发生这种情况后立即返回,而不是等待剩余的 55 分钟。 @DavidSchwartz 不适用于 bool 等原子数据类型。原子数据类型只是为了实现无锁编程 @IvanMolodetskikh 这取决于您收到的确切类型。例如,如果它在 TCP 连接上,则使用shutdown 使read 中止。或者您可能想要减少超时,检查布尔值,然后更快地重试关闭。它非常具体到具体的用例。

以上是关于在互斥锁解锁时取消阻止定时接收的主要内容,如果未能解决你的问题,请参考以下文章

linux互斥锁简介(内核态)

第29课 互斥量与自解锁(std::mutex和lock系列)

go sync包分析

锁定未锁定的互斥体的效率如何?互斥锁的成本是多少?

std::mutex 如何在不同的线程中解锁?

在使用 boost 共享互斥锁时,我应该在啥情况下使用 owns_lock() 函数