【问题标题】:Dealing with thread in C# (deadlock)在 C# 中处理线程(死锁)
【发布时间】:2014-02-26 10:58:40
【问题描述】:

我在 C# 应用程序中使用线程。我有以下情况:

线程 A,调用线程 B,使用以下代码:

ThreadStart t = () => StreamManager.ManageStream.mixThread(ref streamClosed, ref opEnded);
Thread threadB = new Thread(t);
threadB.Start();

线程 B 重复做这个工作:

while (!streamClosed)
    {
         System.Threading.Thread.Sleep(3000);
         //some stuff here
    }
opEnded = true;

布尔值 streamClosed 和 opEnded 通过引用从线程 A 传递到线程 B(使用 ref 关键字)

线程A,启动线程B后,进行如下操作:

streamClosed = true;
while(!opEnded)
{
    System.Threading.Thread.Sleep(1000); //wait 
}

线程 B 停止工作。但在某些情况下,似乎处于死锁状态,因为我从 Windows 中的活动管理器中将其杀死,所以一直处于阻塞状态。

怎么了?

【问题讨论】:

  • 可以显示调用代码吗?
  • 是的,我已经编辑了我的问题
  • 您是否正在尝试实施合作取消?有更简单的方法可以实现这一点。
  • 真正的线程,也传递一个队列 ConcurrentQueue queue

标签: c# .net multithreading thread-safety


【解决方案1】:

将opEnded 定义为volatile。

它可能正在被缓存(由编译器/优化器)。


但对于更深层次的错误代码,这是一种快速且最小的修复方法。

真正的代码不应该Sleep()。有很多更好的方法可以使线程彼此同步。使用哪一个在很大程度上取决于您实际想要做什么。你不应该actually use volatile。

【讨论】:

  • 谢谢,但为什么使用 volatile 对我有帮助?
  • 它可以防止缓存。
  • 嗯好的,但为什么在某些情况下应用程序运行良好?只有某些时候机制会中断?但是我将其声明为静态的。在这种情况下我可以将其声明为 volatile 吗?
  • 我不知道“某些情况”的详细信息,但在某些情况下,锁定或其他操作可能会导致内存栅栏。 Iow,这取决于//some stuff here
  • 我会使用lock 而不是volatile。有关该主题,请参阅 Eric Lippert 的博客:blogs.msdn.com/b/ericlippert/archive/2011/06/16/…
猜你喜欢
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多