线程同步和中止

时间:2011-01-17 23:18:33

标签: c# multithreading c++-cli

我在结束我的一个帖子的工作时遇到了一些问题。首先要做的是这里的应用程序“布局”:

线程1 - 工作线程(C ++ / CLI) - 按预期运行和终止

for(...)
{
  try
  {
    if(TabuStop) return;
    System::Threading::Monitor::Enter("Lock1");
    //some work, unmanaged code
  }
  finally
  {
    if(stop)
    {
      System::Threading::Monitor::Pulse("Lock1");
    }
    else
    {
      System::Threading::Monitor::Pulse("Lock1");
      System::Threading::Monitor::Wait("Lock1");
    }
  }
}

线程2 - 显示结果线程(C#)

        while (WorkerThread.IsAlive)
        {
            lock ("Lock1")
            {
                if (TabuEngine.TabuStop)
                {
                    Monitor.Pulse("Lock1");
                }
                else
                {
                    Dispatcher.BeginInvoke(RefreshAction);

                    Monitor.Pulse("Lock1");
                    Monitor.Wait("Lock1", 5000);
                }

            }
           // Thread.Sleep(5000);
        }

我试图从应用程序主线程中关闭整个事情,如下所示:

        TabuEngine.TabuStop = true; //terminates nicely the worker thread and 
        if (DisplayThread.IsAlive)
        {
            DisplayThread.Abort();
        }

我也试过使用DisplayThread.Interrupt,但它总是在Monitor.Wait上阻塞(“Lock1”,5000);我无法摆脱它。这有什么不对?我该如何执行同步并让它完成它应该做的工作?

//编辑 我现在甚至不确定使用“Lock1”字符串的技巧是否正常工作并且锁定放在同一个对象上。

2 个答案:

答案 0 :(得分:2)

使用您可以在MSDN (Example 2)上找到的监视器进行生产者/消费者同步的一个很好的例子。 有两个线程(生产者和消费者,类似于你的情况),但同步是通过引入锁定共享资源的第三类来完成的。示例提供了完整的源代码,因此我没有在此处发布。

答案 1 :(得分:1)

这些是监视器,而不是自动重置或手动重置事件。您需要检查条件才能正确使用等待。否则,如果您在开始等待之前Pulse,则会错过Pulse。通常情况下,模式如下:

主题A:

 lock(x)
 {
    ... work ....
    while(!some_condition)
      Monitor.Wait(x)
 }

主题B:

lock(x)
{
   ... other work ...
   some_condition = true;
   Monitor.Pulse(x)
}

通过在保持锁定的情况下操纵和检查some_condition,我们确保无论脉冲何时发生(在我们开始在A中或之后等待之前),A总是可以做出适当的反应,而不是永远等待已经发生的脉冲。