【问题标题】:How to find out if we are running in main thread?如何判断我们是否在主线程中运行?
【发布时间】:2015-11-23 11:21:34
【问题描述】:

我们可以通过在main函数的开头调用std::this_thread::get_id()来获取主线程的id,比如this answer suggests。然后我们可以将这个id 存储在一个全局变量中,并与std::this_thread::get_id() 的调用进行比较。

但是,这迫使我们更改main 函数。有没有办法创建一个这样做的 library 函数?我正在考虑使用用std::this_thread::get_id() 表达式初始化的全局变量。由于全局变量(具有静态持续时间的变量)相对较早地初始化,因此不太可能(但并非不可能,请参阅:deferred dynamic initialization)在这些变量初始化之前产生线程。

我还可以使用一个辅助函数初始化全局变量,该函数枚举所有线程并选择创建时间最早的线程(基于this answer)。

我对多线程非常陌生,因此非常欢迎任何建议或指导。

【问题讨论】:

  • 为什么?它对运行任何特定函数调用的线程有什么影响?
  • 这样做的目的是什么?在您的代码中,您应该知道是否在主线程上调用了函数,就这么简单。 :)
  • @DanielSanchez 有时它对完整性检查很有用,例如如果您正在设计一个通用库,例如​​,要知道哪个线程将调用一个函数,这并不总是那么容易。在这种情况下,库将与任何特定线程分离,并且它的函数可能会被任何线程调用。
  • 在 Windows 中,进程可以比主线程寿命更长并产生更多线程。 blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx 如果您的库在主线程终止后 由辅助线程加载怎么办?
  • 如果您解释您正在尝试解决的实际问题,而不是寻求帮助实施您选择的解决方案,您将获得更好的答案。

标签: c++ multithreading c++11


【解决方案1】:

没有主线程这样的东西。有一个线程首先启动,但所有线程都是一等公民。通过修改链接器标志,我可以轻松创建一个程序,其中执行main() 的线程不会是首先启动的线程。

重新思考你的设计。

【讨论】:

  • 我几乎同意。如果没有链接器标志,在 Windows 中,您可以在运行 WinMain 的线程中使用 ExitThread,而在 POSIX 中,您可以在运行 main 的线程中使用 pthread_exit。加载库时,第一个线程可能不再存在。然而,即使在两个系统中都有一个原始程序入口点,您也无法避免它在库加载和初始化之后运行
  • @PauloMadeira,加载和初始化库是一个很大的话题,尤其是延迟绑定:) 幸运的是,我在回答中没有提到这一点——我只是说线程正在执行main()
  • 你是对的,你可以有一个在另一个线程中运行 mainWinMain 的原始入口点。
  • 仅供参考,“主线程”(又名“UI 线程”)是 iOS/macOS 上使用的术语。
  • @Jyaif 在问题中都看不到这些标签。
【解决方案2】:

编辑

考虑到@ta.speot.is 和@David Schwartz 所说的,这不是获取主线程 ID 的可靠方法。

你可以在某处创建一个静态变量,用当前线程的 ID 进行初始化。

const std::thread::id MAIN_THREAD_ID = std::this_thread::get_id();

然后在其他地方:

if (std::this_thread::get_id() == MAIN_THREAD_ID)
{
    std::cout << "main thread\n";
}
else
{
    std::cout << "not main thread\n";
}

【讨论】:

  • 谢谢。这是我考虑的第一件事,但是,问题是我不能保证MAIN_THREAD_ID 将在主线程中初始化。还是我???
  • this 所以是的,它应该在同一个线程上运行main 运行。
  • Hm 在 Windows 10 下的 Visual Studio 2015 中在普通控制台应用程序中为我工作。
  • 这行不通。一方面,线程 ID 可以重复使用。 “一旦线程完成,std::thread::id 的值可能会被另一个线程重用。”
  • 线程id不是只有在线程完成执行后才会重用吗?程序何时结束,OP没有提到应用程序生命周期之外的持久性。
【解决方案3】:

如果您使用的是 MFC。您可以查看AfxGetMainWnd()。如果它返回一个 pWnd 那么你有(MFC)主线程。免责声明:如果您没有操作过m_pMainWnd 指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2015-08-14
    • 2018-09-13
    相关资源
    最近更新 更多