使用Critical Section在线程之间进行同步

时间:2013-06-04 12:17:32

标签: multithreading events synchronization message critical-section

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

ThreadA始终处于关键部分,将数据弹出队列并在套接字上发送。

当从ThreadB到ThreadZ的任何线程想要进入临界区时,它希望ThreadA只在那时离开临界区。然后它进入关键部分,将一些数据推入队列并留下关键部分。

我有两个问题:

  1. ThreadB-Z(谁想要进入关键部分) 告诉ThreadA何时离开关键部分 访问关键部分。
  2. 我尝试了SetEvent或PostThreadMessage的想法 threadA离开关键部分,但我无法处理 任何事件或线程消息,因为ThreadA不断弹出 使用while(1)从队列中取出数据并且没有消息循环或 WaitforSingleObject()类型用于处理事件或线程消息 :(
  3. 我喜欢陷入这种境地。欢迎任何帮助/建议。提前谢谢。

1 个答案:

答案 0 :(得分:0)

这里真正的问题是“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

微软的一句好话:“当你使用任何类型的多线程时,你可能会暴露自己非常严重和复杂的错误”[来源:MSDN]