我在Windows上使用MinGW-w64。我试图弄清楚CRT启动功能内部正在发生什么。程序入口点为mainCRTStartup()
。该函数初始化缓冲区安全性cookie,然后跳转到__tmainCRTStartup()
,最终调用main()
。在__tmainCRTStartup()
的{{3}}内部,有一个奇怪的操作:
while((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, fiberid, 0)) != 0)
{
if (lock_free == fiberid)
{
nested = TRUE;
break;
}
Sleep(1000);
}
此处fiberid
设置为线程堆栈的基地址。
该代码似乎阻止了多个线程或光纤同时初始化CRT。但是,为什么会有多个线程运行__tmainCRTStartup()
呢?由于所有线程共享相同的地址空间,仅初始化一次CRT是否足够?同样很难理解的是循环内部的if块。要触发此条件,必须将__native_startup_lock
设置为fiberid
,这意味着所讨论的线程已退出循环。我在这里看不到MinGW试图支持哪种功能。
更新:
好。我找到了带注释的CRT源代码的Visual Studio 2013副本。这是注释:
/*
* There is a possiblity that the module where this object is
* linked into is a mixed module. In all the cases we gurantee that
* native initialization will occur before managed initialization.
* Also in anycase this code should never be called when some other
* code is initializing native code, that's why we exit in that case.
*/
这也许可以解释循环中的nested
条件,但是我仍然不明白为什么这里涉及多线程。