【发布时间】:2015-07-22 16:38:13
【问题描述】:
在我的应用程序中,我使用这个 sn-p 运行后台操作:
m_thread = std::thread(&MyClass::BackOp, this);
在我的应用程序调用函数Close() 中有时会有不同的线程(可能包括m_thread 本身),它等待后台线程完成其操作:
if(m_thread.joinable()) m_thread.join();
这是不安全的行为,如果我是对的,它可能会导致死锁。
如果它在我的后台线程中运行,我可以在我的Close() 函数文本中确定跳过“加入”吗?
谢谢!
【问题讨论】:
-
为什么不使用同步原语,比如可以定义某种“临界区”的互斥锁?
-
首先,在我的 nanospeed 例程中,临界区/互斥锁非常慢。其次,我只是在这个问题中不需要它,在我的函数
Close()中,我只等待线程完成。可能,这可以从我的应用程序中的任何线程执行,包括m_thread本身。 -
请注意:
if(m_thread.joinable()) m_thread.join();理论上可能导致std::system_error类型的异常和代码invalid_argument,如果在评估m_thread.joinable()之后但在执行m_thread.join()之前,m_thread完成执行并由第三个线程加入。另请注意,对std::thread对象的操作是不同步的,因此不同线程访问同一个m_thread的整个业务本质上是有风险的。 -
@bogdan 所以没有任何解决方案可以在没有
try..catch的情况下安全地调用join()..? -
即使捕获异常,您的代码也无法保证。如果不知道在存在多个线程的情况下您对
Close()语义的确切要求是什么(这是一个单独的问题),就很难给出解决方案。如果您确实希望多个线程同时等待后台线程完成,则需要适当的同步机制来可靠地执行此操作 - 例如std::condition_variable或std::shared_future。
标签: c++ multithreading c++11 concurrency stl