【问题标题】:Wait immediately after Releasing mutex, switching threads释放互斥量后立即等待,切换​​线程
【发布时间】:2017-06-24 18:17:41
【问题描述】:

假设我有一个名为 Mutex1 的互斥体(或信号量)

private static readonly SemaphoreSlim Mutex1 = new SemaphoreSlim(0, 1);

下面的代码会一直按我的预期工作吗?

线程 A

await Mutex1.WaitAsync(); // wait in thread "A" until thread "B" releases mutex

线程 B

Mutex1.Release();
await Mutex1.WaitAsync(); // thread A should continue and thread B should wait.

线程 B 中的 Mutex1.Release 是否总是保证会导致线程 A 中的继续?

我的猜测答案是否定的,因为在线程 A 继续之前,线程 B 可能会再次等待,并且由于“等待线程”没有排队,线程 B 可能会再次继续,而不是线程 A。我说的对吗?


我目前使用的安全方法是使用名为 Mutex2 的附加字段。

private static readonly SemaphoreSlim Mutex2 = new SemaphoreSlim(0, 1);

线程 A

await Mutex1.WaitAsync(); // wait in thread "A" until thread "B" releases mutex

线程 B

Mutex1.Release();
await Mutex2.WaitAsync(); // notice Mutex TWO

现在我确定线程之间的切换得到了正确处理,但我想知道我是否可以保存一个字段并安全地使用第一种方法。请注意,此操作被包裹在锁中,因此它是单线程且安全的。

(对于那些好奇的人,这是使用 UWP 应用程序服务在两个应用程序之间进行同步通信的应用程序的一部分)

【问题讨论】:

    标签: c# multithreading mutex semaphore


    【解决方案1】:

    来自https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx 我们有:

    如果多个线程被阻塞,则没有保证的顺序(例如 FIFO 或 LIFO)来控制线程何时进入信号量。

    所以,对我来说,这意味着苗条信号量不会将请求排队。

    而且,您的第一种方法有竞争条件。也就是说,线程 B 可以释放互斥体并立即重新获取它,从而将线程 A 锁定一段时间。

    因此,您可能必须使用两个信号量方法。或者,使用支持 [公平] 等待者队列的不同同步原语。

    【讨论】:

      【解决方案2】:

      按照您的使用方式,您应该尝试使用AutoResetEventhttps://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx

      这会做你想做的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-10
        • 2017-07-14
        • 2021-01-29
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        • 2016-11-05
        相关资源
        最近更新 更多