【问题标题】:How to stop C++ program from crashing when closing while a condition_variable is waiting?在条件变量等待时关闭时如何阻止 C++ 程序崩溃?
【发布时间】:2017-11-21 19:23:10
【问题描述】:

我正在为我的项目构建一个多线程服务器。
我正在使用条件变量和锁。
我将条件变量 cv 作为全局变量,将互斥体 _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:向服务或函数传递了无效参数。

可能是什么问题?

【问题讨论】:

  • 推送消息时需要同步。
  • 我最喜欢的停止从阻塞队列中获取东西的线程的方法是给它一个毒丸——一个线程的主循环通过其已知地址或特殊地址识别的杰出对象内容。线程查看它从队列中弹出的每个对象,当它看到毒丸对象时,它知道清理并退出。

标签: c++ multithreading mutex condition-variable


【解决方案1】:

如果你想要干净的关机,你需要把它设计成一切。您的服务器需要一个关闭函数(可以是它的析构函数)。而且您的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;
 }
}

【讨论】:

  • 问题是当用户按下终端上的 X 按钮关闭它时,由于某种原因,析构函数永远不会被调用,程序就会崩溃。
  • 那么你的错误在别处。就像我说的那样,您需要将干净的关机设计到 everything
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多