【问题标题】:C# variable thread safetyC#变量线程安全
【发布时间】:2013-07-31 16:27:44
【问题描述】:

关于一次从多个线程访问局部变量的几个问题:

  1. 我有多个线程写入和读取一个变量的值,我是否应该同步访问它?

  2. 每隔几秒从 Thread1 更新该变量,每隔几秒从 Thread2 读取并更新到数据库。

  3. 如果我没有任何逻辑并且没有任何并发​​问题,会出现哪些问题?

  4. 我应该为此使用 volatile 吗?

编辑:

我想强调我没有任何并发​​问题。这是我的具体方案:

一个。我的变量名称是 pingLatency,它测量 ping 延迟

b. Thread1 每 10 秒向 8.8.8.8 发送一个 ping,并将延迟写入pingLatency

c。 Thread2 每 10 秒更新一个值为pingLatency 的相关字段。

d。 Thread2 每次更新相同的数据库行。

现在,我正在使用此数据库字段来监控网络连接。我的问题是 - 是否存在变量未更新或由于线程安全问题而引发异常的情况?我想避免使用lock,因为它看起来有点矫枉过正。

你怎么看?

【问题讨论】:

  • 答案:1. 视情况而定; 2. 视情况而定; 3.地段; 4:可能。您是否尝试过搜索 Stack Overflow 以查找讨论此问题的现有问题?这里有很多与线程安全相关的问题。
  • “局部变量”到底是什么意思?发布一个例子。
  • 我假设当您说 variable 时,实际上是指 field,因为 variable 始终是 local,然后您将无法从多个线程访问它。
  • 由于第一行的链接,我检查了@Mgets 作为正确答案。
  • @lasse 你可以从多个线程访问本地没有问题。不,变量并不总是本地的。变量是任何存储位置。

标签: c# multithreading thread-safety


【解决方案1】:
  1. 是的,您应该同步访问它,如果它是原始类型,则有methods to do this for you without locks
  2. 没有评论
  3. 不确定您的意思...很可能您最终会在数据库中插入错误的值
  4. Don't use volatile, per Eric Lippert, 太复杂了,语义也很奇怪。

小心破坏内存模型,C# 在为无数据争用程序 (SC-DRF) 使用顺序一致性方面大体上遵循大多数其他语言。 Volatile 打破了这一点,所以只需使用锁来防止数据竞争。

至于lock,它并没有想象的那么重,在大多数情况下,锁不会在你想象的场景中被争用。因此,在大多数情况下,获取锁应该是无痛的。

【讨论】:

  • Eric 并没有说你不应该使用volatile,他说它可能不会像你想象的那样做。 volatile 是完全合适的,如果您知道它的含义和作用。
  • @LasseV.Karlsen 鉴于文档中的内容与 Eric 不同,我将避免使用 volatile,因为这意味着即使 MS 也不确定 volatile 的含义。 Eric 也很清楚 volatile 破坏了 SC-DRF。
  • Volatile 确实意味着原子,因为只有原子字段可能是 volatile。
  • @EricLippert 我可能读错了你的旧博客,但似乎volatile 在 SC-DRF 方面存在问题,尤其是在顺序一致性和数据竞争位方面......
  • Volatile 不会将非原子更新变成原子更新。例如,一个 volatile 字段上的两个并发 x++ 仍然可能丢失更新。但是每次读写都是原子的。它们不能被撕裂。
【解决方案2】:

如果您想要 .NET 托管并行性,请使用内置的好东西。 Task Parallelism。这将为您管理线程,您可以使用内置的线程安全变量,就像数组/列表等于 ConcurrentBag 等一样。

【讨论】:

    【解决方案3】:

    如果对您的变量的访问是原子的并且没有逻辑问题,那么您就可以了。 根据this,你可以知道你是否使用了原子变量。

    【讨论】:

    • 假设他知道诸如内存栅栏、易失性字段的使用等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    相关资源
    最近更新 更多