如何判断我们是不是在主线程中运行?
Posted
技术标签:
【中文标题】如何判断我们是不是在主线程中运行?【英文标题】: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 如果您的库在主线程终止后 由辅助线程加载怎么办? 如果您解释您正在尝试解决的实际问题,而不是寻求帮助实施您选择的解决方案,您将获得更好的答案。 【参考方案1】:没有主线程这样的东西。有一个线程首先启动,但所有线程都是一等公民。通过修改链接器标志,我可以轻松创建一个程序,其中执行main()
的线程不会是首先启动的线程。
重新思考你的设计。
【讨论】:
我几乎同意。如果没有链接器标志,在 Windows 中,您可以在运行WinMain
的线程中使用 ExitThread
,而在 POSIX 中,您可以在运行 main
的线程中使用 pthread_exit
。加载库时,第一个线程可能不再存在。然而,即使在两个系统中都有一个原始程序入口点,您也无法避免它在库加载和初始化之后运行。
@PauloMadeira,加载和初始化库是一个很大的话题,尤其是延迟绑定:) 幸运的是,我在回答中没有提到这一点——我只是说线程正在执行main()
。
你是对的,你可以有一个在另一个线程中运行 main
或 WinMain
的原始入口点。
仅供参考,“主线程”(又名“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
指针。
【讨论】:
以上是关于如何判断我们是不是在主线程中运行?的主要内容,如果未能解决你的问题,请参考以下文章
[转]Android限制只能在主线程中进行UI访问的实现原理