I am building a multi-threaded server for my project.
I am using condition variables and locks.
I have the condition variable cv as global and the mutex _mtxReceivedMessages as a class member.
This is the function that waits for the user message:
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
}
}
This is the function that calls the notifies the cv:
void Server::addReceivedMessage(ReceivedMessage* msg)
{
_queRcvMessages.push(msg); // Adds the message to the queue
cv.notify_all(); // Unlockes all locked functions
}
The Problem is that if I try to close the program while the function handleReceivedMessages is waiting (before the function addReceivedMessage was called) the program crashes,
but if I remove the line:
while (_queRcvMessages.size() == 0) cv.wait(lck); // As long as there are 0 messages in the queue
The program exits just fine.
The program crashes with: Unhandled exception at 0x7748507C (ntdll.dll) in Nuvola.exe: 0xC000000D: An invalid parameter was passed to a service or function.
What can be the problem ?
If you want clean shutdown, you need to design it into everything. Your server needs a shutdown function (which can be its destructor). And your handleReceivedMessages
function needs a way to stop on shutdown.
For example, you could add a bool shutdown;
to your Server
class. To shut the class down, acquire the mutex, set shutdown
to true
, and signal the condition variable. (You may need to join
the server's thread if it has one.)
Your handleReceivedMessages
function would then look more like this:
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;
}
}
User contributions licensed under CC BY-SA 3.0