【问题标题】:C++11 deferred "thread" creation (i.e., specify thread function but do not wait physical thread to be created)C++11 延迟“线程”创建(即指定线程函数但不等待创建物理线程)
【发布时间】:2013-03-28 03:13:57
【问题描述】:

我的目标是我在标题中所问的,当使用带有线程函数(非 void ctors)的 std::thread ctor 时,我希望调用者线程不等待子线程被物理创建和恢复

当我在加载 DLL 期间尝试使用线程函数创建 std::thread 对象时,我的问题出现了(在 Windows 中)。 这是一个问题,因为(据我所知) - 线程构造函数尝试创建物理线程 - 不知何故(对我来说不幸)Ctor 等待物理线程恢复(上线) - 不幸的是,如果线程是在函数调用期间创建的,Win API 不允许线程在 LoadLibrary 调用中恢复。 - 所以我有一个死锁:LoadLibrary 创建一个线程,它等待它恢复,Windows 不让它恢复。

我可以为这个问题发明一些解决方案(通过有一个不使用 std::thread 的不同线程,它将构造额外的线程(std::threads),但是我错过了使用“仅”std 的全部要点: :thread 满足我的线程需求:-))。 但是,如果 std::thread 是用线程函数(或 lambda 或其他)构造的,最好告诉它不要等待物理线程恢复。 有没有办法做到这一点,或者我应该去解决问题? 谢谢

  • 另一个需要相同的情况 在快速路径中,我可以(懒惰地)创建一个 std::thread 对象,向它发布一些任务(许多任务可能),然后继续(在快速路径中)而不会延迟!我可能不在乎何时真正创建并恢复子线程。 如果不能在这样的快速路径中或在 DllMain 等期间懒惰地创建物理线程,那将是很可惜的。

【问题讨论】:

  • 您是在 DllMain 中创建线程吗?
  • 实际上我正在一个 DLL 范围的全局 C++ 对象 ctor 中创建线程。我相信做这些工作人员的 CRT 初始化是从 DllMain 调用的
  • 他们在DllMain 被输入之前被调用,我想说。老实说,我建议您将线程的创建推迟到DllMain 返回之后。从您的 dll 中导出 initialize() 函数并要求加载模块来调用它(在加载 dll 之后)。然后initialize() 函数将创建启动线程的对象。
  • 可以std::async 以任何方式帮助您吗?
  • 我已经导出了这样的初始化(和清理)函数。如果我找不到直接的解决方案,我会按照你的建议去做。谢谢安迪。

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


【解决方案1】:

问题不在于您创建线程的方式,而在于您在加载 DLL 时创建线程的事实本身。虽然对CreateThread 的调用可能是安全的(只要启动的线程不执行等待操作),it is in general a bad idea to create threads during DllMain

您应该在这里做的是导出一个初始化函数并要求加载模块在您的 DLL 加载后调用它。然后初始化函数将实例化所有需要的对象并创建所有必要的线程。

另见this Q&A on StackOverflow

【讨论】:

  • 那么我可以假设没有办法做我需要的事情:如果要创建一个非空的 std::thread ,它必然会阻塞调用者,直到真正创建物理线程并且简历?可怜……
  • @mami:是的,没有办法,因为C++11标准规定std::thread的构造完成必须与线程函数的启动同步(§ 30.3.1.2 /5).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-28
  • 2011-05-10
  • 2020-03-15
  • 2011-10-18
  • 1970-01-01
相关资源
最近更新 更多