【问题标题】:Determine if code is running in specific thread确定代码是否在特定线程中运行
【发布时间】: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_variablestd::shared_future

标签: c++ multithreading c++11 concurrency stl


【解决方案1】:

我可以在我的Close() 函数中确定它是否在我的后台线程中运行,以跳过“加入”吗?

是的,您可以使用std::this_thread::get_id() 函数并与m_thread.get_id() 进行比较以确定例程是否在同一个std::thread 实例中运行。

【讨论】:

  • 是什么让你认为joinable() 在当前执行线程上调用不会返回true?
  • @Joker m_thread.join(); 但是,如果 m_thread 是当前执行线程 - 带有代码 resource_deadlock_would_occurstd::system_error - 将引发异常 - 所以你不会有死锁。
  • @bogdan 怎么样,如果线程已经完成执行,该例程是否可以在线程内实际执行,以使其返回true
  • @πάνταῥεῖ m_thread 操作本身是一个长期过程,可能会决定使用我的问题中描述的共享 Close() 函数来停止自己。这是很常见的情况。还是你不懂线程?
  • @Joker 对不起,我对 joinable() 的看法是错误的。将从答案中删除。
【解决方案2】:

我相信您想使用std::this_thread::get_id 并将其结果与std::thread::get_id(您的“背景”线程)的结果进行比较。或者有一些线程局部变量(可能在线程开始时存储这些变量等)。

【讨论】:

  • 正确,但由于堆缓存,跨多个线程共享变量不安全
【解决方案3】:

您应该使用if(m_thread.joinable()) m_thread.join();。没听说过不安全。

【讨论】:

  • 如果在m_thread 上下文中调用Close() 会怎样?它将自己加入,这应该解除锁定吗?
  • @Joker 根据标准,30.3.1.5 个线程成员,join 要求线程是“可连接的”,并且会在 this->get_id() == std::this_thread::get_id() 时检测情况 - 将抛出异常,意思是 resource_deadlock_would_occur
猜你喜欢
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2012-03-21
相关资源
最近更新 更多