从很多线程中,我发现 C# int/float 是线程安全的。但是我看到很多开发人员使用 Interlocked.Increment/CompareExchage 进行多线程应用程序。任何人都可以告诉我使用这些构造的原因。 更新: 我知道这些构造。我只是想问如果 int 是线程安全的,为什么我们需要这些构造?
2 回答
任何人都可以告诉我使用这些构造的原因。
这与读/写的线程安全无关。但是关于 COMPLETE 操作的线程安全。
增量是读,加1,写。联锁保证在一次“交易”中发生。与比较/交换相同。
如果您不使用某种锁定来编写它,那么您可能会在操作之间被打断。
读增量写
这三个步骤中的每一个都是原子的,但不是组合。当您回写时,其他人可能已经更改了值 - 互锁确保整个操作是原子的。
如前所述,您可能想在谷歌上搜索它。
但是,要回答“为什么要使用 InterlockedIncrement(&c.)?”的问题,虽然您确实可以始终执行一个简单的 int 访问并且保证不会返回任何半写的内容,但您不能保证诸如增量之类的“读取和修改”操作将达到您的预期。
InterlockedIncrement 和它的同类,都保证操作将以原子方式执行 - 所以在 InterlockedIncrement 本身的情况下,如果两个线程都在同一个 int 上调用它,那么 int 保证增加两次并返回正确的值调用线程。但是,做一个简单的 'i++;' 同时在两个线程上(对于相同的“i”)可能会导致读取的值不正确。
这是因为诸如“i++”之类的增量被分解为至少两个机器指令:“读取值”和“增加值”(或者更糟的是:“读取”、“增加局部值”、“写入”) . 如果两个线程同时执行此操作,那么它们可能都读取值 0,但增加的值最终可能为 2。