【问题标题】:Can a .NET thread be interrupted between a method returning and assigning its return value (without terminating the process)?.NET 线程能否在方法返回和分配其返回值之间中断(不终止进程)?
【发布时间】:2019-01-03 09:44:36
【问题描述】:

.NET 线程是否有可能在方法返回和将其返回值分配给变量/字段的时间之间以某种方式停止执行?当然,有可能整个进程被终止或者机器被关闭,但是在进程继续运行的情况下这可能吗?

例如:

class Test
{
     public static readonly Mutex MyMutex = new Mutex(false);
     public static bool MutexAcquired = false;

     private static bool AcquireMutex() => MyMutex.WaitOne(1000);

     public static void DoSomething()
     {
         MutexAcquired = AcquireMutex();
     }
}

运行DoSomething() 是否有可能获得互斥锁(WaitOne 返回 true),但在值 MutexAcquired 从 false 更改为 true 之前,某些东西会中断线程(但进程以某种方式继续运行,所以仍然可以读取MutexAcquired 的错误值)?如果MutexAcquired 是本地而不是字段,会有什么不同吗?

(我意识到,正如所写,AcquireMutex 方法可能会被内联,但我们假设它在实践中更复杂,所以它不是内联的。)

【问题讨论】:

  • 是的,这完全有可能。线程可以随时中断。只有原子操作可以保证始终完整执行(或根本不执行)。
  • 自动设置布尔值的Monitor.Enter() 的重载被添加到 .NET 4 时间范围内,这正是因为尝试在方法返回后分配 的速度。 (在此之前的极少数情况下,使用Monitor 的lock 可能会泄漏锁)

标签: c# .net multithreading thread-safety


【解决方案1】:

是的,完全有可能。分配不能保证是原子的,线程可以随时中断(没有人知道它的时间片何时到期,或者必须调度更高优先级的线程)。

然后,您还需要考虑编译器或 CPU 可以优化您的代码,使其更不安全。阅读更多here。

如果MutexAcquired 是一个局部变量,它只能被当前线程访问,因此不需要锁定。只有当多线程访问数据时才需要加锁/原子操作。

【讨论】:

    猜你喜欢
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多