我正在为我的项目构建一个多线程服务器 我正在使用条件变量和锁 我将条件变量cv作为全局,将mutex _mtxReceivedMessages作为类成员。
这是等待用户消息的功能:
void Server::handleReceivedMessages()
{
while (1)
{
std::unique_lock<std::mutex> lck(_mtxReceivedMessages);
while (_queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue
}
}
这是调用通知cv的函数:
void Server::addReceivedMessage(ReceivedMessage* msg)
{
_queRcvMessages.push(msg); // Adds the message to the queue
cv.notify_all(); // Unlockes all locked functions
}
问题是如果我在函数handleReceivedMessages等待时尝试关闭程序(在调用函数addReceivedMessage之前),程序崩溃,
但如果我删除该行:
while (_queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue
程序退出就好了。
程序崩溃:Nuvola.exe中0x7748507C(ntdll.dll)处的未处理异常:0xC000000D:将无效参数传递给服务或函数。
可能是什么问题?
答案 0 :(得分:5)
如果要干净关闭,则需要将其设计为所有内容。您的服务器需要一个关闭功能(可以是它的析构函数)。而handleReceivedMessages
函数需要一种停止关闭的方法。
例如,您可以向bool shutdown;
课程添加Server
。要关闭课程,请获取互斥锁,将shutdown
设置为true
,并发出条件变量信号。 (如果有服务器的线程,您可能需要join
。)
您的handleReceivedMessages
功能看起来更像是这样:
void Server::handleReceivedMessages()
{
while (1)
{
std::unique_lock<std::mutex> lck(_mtxReceivedMessages);
while (!shutdown && _queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue
if (shutdown) return;
}
}