【问题标题】:Locking Variables when Threading in C#在 C# 中线程时锁定变量
【发布时间】:2020-12-29 18:30:16
【问题描述】:

我有一个 C# 程序,我在其中生成一个线程来进行一些计算。然后我将计算结果添加到队列中,并且从主线程中,我不断检查队列的长度是否大于 0。如果是,则计算结果出队并在其他地方使用。

我读过我应该在从任一线程访问队列时锁定队列,因为如果两个线程同时访问它可能会导致问题。但是我应该在对队列执行任何操作时锁定它,还是仅在入队/出队时锁定它?

例如

// In main thread

lock (meshDataQueue) {
  if (meshDataQueue.Count > 0)
  {
    constructMesh(meshDataQueue.dequeue())
  }
}

对比

if (meshDataQueue.Count > 0) {
  lock (meshDataQueue)
  {
    constructMesh(meshDataQueue.dequeue())
  }
}

【问题讨论】:

  • 由于队列在线程内发生变化,所以在检查计数之前应该先锁定它。
  • 为什么不使用 ConcurrentQueue?
  • @Charlieface 我不知道那个数据结构。谢谢。
  • @ShreyJoshi - 您应该始终使用lock 访问Queue,但您应该养成不锁定Queue 实例的习惯- 始终创建一个新的范围尽可能有限的对象。

标签: c# multithreading queue


【解决方案1】:

是的,无论何时对Queue 实例进行任何操作(包括读取队列的Count 之类的琐事),都应该锁定Queue 实例(始终使用相同的“locker”对象)。 Queue 类不是线程安全的,因此要使其行为保持定义,您必须确保它一次由一个线程访问(在从线程切换到线程时具有适当的内存屏障,lock 语句稳健提供)。否则,您将进入未定义的行为领域,所有保证都已关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多