首页 > 解决方案 > 通过多个线程初始化 C 运行时?

问题描述

我在 Windows 上使用 MinGW-w64。我试图弄清 CRT 启动函数内部发生的事情。程序入口点是mainCRTStartup(). 该函数初始化缓冲区安全cookie,然后跳转到__tmainCRTStartup(),最终调用main()。现在在源码里面__tmainCRTStartup()有一个奇怪的操作:

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 在这里试图支持什么样的功能。

更新

好的。我找到了一份 Visual Studio 2013 的副本,附带了带注释的 CRT 源代码。这是注释:

/*
 * 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循环中的条件,但我仍然不明白为什么这里涉及多线程。

标签: windowsmultithreadingmingw-w64crt

解决方案


推荐阅读