Multithreading 异步网络条件
我正在为一个网络应用程序编写一个客户端,我想将消息的接收和处理分离到不同的线程 这是我目前的解决方案:Multithreading 异步网络条件,multithreading,networking,asynchronous,synchronization,race-condition,Multithreading,Networking,Asynchronous,Synchronization,Race Condition,我正在为一个网络应用程序编写一个客户端,我想将消息的接收和处理分离到不同的线程 这是我目前的解决方案: Mutex mutex; Queue queue; recv() { while(true) { messages = receive_some_messages(); mutex.lock(); queue.add(messages); mutex.unlock(); process.not
Mutex mutex;
Queue queue;
recv()
{
while(true)
{
messages = receive_some_messages();
mutex.lock();
queue.add(messages);
mutex.unlock();
process.notify();
}
}
proc()
{
while(true)
{
block_until_notify();
Queue to_process;
mutex.lock();
to_process.add( queue.take_all() );
mutex.unlock();
foreach(message in to_process)
{
process_message(message);
}
}
}
但是,这有一个竞争条件:
proc()
{
while(true)
{
block_until_notify();
Queue to_process;
mutex.lock();
to_process.add( queue.take_all() );
foreach(message in to_process)
{
process_message(message);
}
mutex.unlock();
}
}
但这意味着线程以独占方式运行:recv或proc都处于活动状态,但不是两者都处于活动状态
解决方案2
我可以移除该块并通知
recv()
{
while(true)
{
messages = receive_messages();
mutex.lock();
queue.add(messages);
mutex.unlock();
}
}
proc()
{
while(true)
{
Queue to_process;
mutex.lock();
to_process.add( queue.take_all() );
mutex.unlock();
foreach(message in to_process)
{
process_message(message);
}
}
}
但这意味着proc将在一个繁忙的等待循环中运行,只有在recv向队列添加消息时才会阻塞
问题
我想要一个解决方案,其中proc和recv不独家运行,没有繁忙的等待。
有人知道我能做什么吗?我想如果消费者在排干队列后检查是否有空队列,你就可以通过了
proc()
{
while(true)
{
Queue to_process;
mutex.lock();
if (queue.empty()) {
mutex.unlock();
block_until_notify();
mutex.lock();
}
to_process.add( queue.take_all() );
mutex.unlock();
foreach(message in to_process)
{
process_message(message);
}
}
}
我相信这会修正你提到的比赛条件 您的
阻塞\u直到\u notify()
函数可能是一个条件变量。方法是更改该函数,以便锁定互斥锁,检查队列是否为空,然后等待通知。如果队列不是空的,则继续处理它。处理完队列后,返回block_notify函数并重复该过程,在阻塞之前再次检查队列是否为空
如果您没有使用某种条件变量,那么我建议使用信号量。在Windows系统上,每次消息添加到队列中时,您都会调用
releasesmaphore
。接收器将调用信号量句柄上的WaitForSingleObject
。这将在循环中完成,循环将继续重复,即使队列为空,直到等待阻塞。谢谢您的回答。“我也相信这会解决比赛条件。”达马库斯塔斯:这实际上是另一个答案第一段中建议的解决方案。谢谢你对信号灯的建议。