【问题标题】:Synchronization done by class destructors由类析构函数完成的同步
【发布时间】:2018-05-08 07:01:03
【问题描述】:

我有关于多线程的问题。我有一个相当大的项目,现在我正在编写一些 exe 客户端来使用所有这些代码。它涉及多线程和进程间通信。我的 main 看起来像这样:

int main(int argc, char** argv)
{
std::unique_ptr<CommunicationWrapper> wrapper;

wrapper = std::make_unique<CommunicationWrapper>(argv[1]);
wrapper->run();

return 0;
}

下面有一个类进行进程间通信,如下所示:

CommunicationEngine::CommunicationEngine()
 : m_processingLoop(std::async(std::launch::async, [this]() { processingLoop(); }))
{}

CommunicationEngine::~CommunicationEngine()
{
   m_processingLoop.wait();
}

//some long function that do a lot of stuff based on messages from anothre process
void CommunicationEngine::processingLoop() const 

这段代码可以正常工作,但我想知道在调用析构函数时进行同步(等待)是否被认为是好的做法和好的设计?这种方法可能存在哪些缺陷?

【问题讨论】:

  • 标准库做到了。如果 std::future 的析构函数是最后一个引用在对 std::async 的调用中创建的共享状态的析构函数,并且该状态尚未准备好,则会阻塞。

标签: c++ multithreading oop thread-synchronization


【解决方案1】:

RAII 通常是一个非常有用的习语,它使您的代码异常安全,并降低在进一步修改过程中出现错误的风险。

你应该做的主要事情是确保你的析构函数不会抛出。

关于std::future::wait 的异常安全性 - 当valid() == falsewait() 之前,它的行为是未定义的,所以你应该在析构函数中调用它之前检查它。

【讨论】:

    【解决方案2】:

    首先,您在提供的代码中不需要任何unique_ptr。只是 CommunicationWrapper(argv[1]).run() 可以。

    其次,我认为总的来说你在做什么没有问题。可以在析构函数中等待线程完成。但是,您应该意识到您的应用程序在线程终止之前不会退出,因此如果其中存在错误,您的应用程序将永远不会退出。有时人们更喜欢定时等待,而不是在一定时间后退出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 2011-02-15
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多