【问题标题】:Synchronization between threads using Critical Section使用临界区的线程之间的同步
【发布时间】:2013-05-30 20:03:59
【问题描述】:

我有多个线程,ThreadA 和 ThreadsB-Z。

ThreadA 始终处于临界区,将数据从队列中弹出并通过套接字发送。

当从ThreadB 到ThreadZ 的任何线程要进入临界区时,它才希望ThreadA 离开临界区。然后它进入临界区,将一些数据推入队列并离开临界区。

我这里有两个问题:

  1. ThreadB-Z 怎么会(谁想进入临界区) 告诉 ThreadA 在需要时离开临界区 访问关键部分。
  2. 我试着用 SetEvent 或 PostThreadMessage 的想法来告诉 threadA 离开临界区,但我无法处理 自 ThreadA 不断弹出以来的任何事件或线程消息 使用 while(1) 将数据从队列中取出,并且没有消息循环或 WaitforSingleObject() 类型的东西来处理事件或线程消息 :(

我就像陷入了这种情况。欢迎任何帮助/建议。提前致谢。

【问题讨论】:

    标签: multithreading events synchronization message critical-section


    【解决方案1】:

    这里真正的问题是“ThreadA 总是在临界区”。 ThreadA 不应该无限期地锁定临界区。

    在 C# 中,ThreadA 的代码如下所示:

    Message message;
    
    // Only lock critical section for the time it takes to modify the queue
    lock(_messageQueueLock){
       message = _messageQueue.Dequeue();
    }
    
    // do something with the message
    

    在我看来,使用临界区时应遵守以下一般经验法则

    • 尽快进入和退出临界区(即尽量减少临界区中的代码量)。
    • 使用临界区来保护资源/资产(例如共享内存、队列、列表等)
    • 避免使用临界区来保护函数/方法调用。如果您从关键部分进行函数/方法调用...您正在增加创建死锁的可能性。
    • 避免尝试从临界区中锁定临界区。否则可能会导致您的应用程序出现潜在的死锁。
    • 避免在临界区尝试访问外部资源(例如执行数据库 SQL 查询)。
    • 在有意义的情况下,我通常喜欢对关键部分使用以下命名约定:如果受保护的资产称为 messageQueue... 那么我将关键部分命名为 messageQueueLock

    来自 Microsoft 的精彩引用:“当您使用任何类型的多线程时,您可能会将自己暴露在非常严重和复杂的错误中”[来源:MSDN]

    【讨论】:

      猜你喜欢
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2016-10-07
      • 2013-05-05
      相关资源
      最近更新 更多