windows - 通过多个线程初始化 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
循环中的条件,但我仍然不明白为什么这里涉及多线程。
解决方案
推荐阅读
- ios - 还原合并的拉取请求
- php - Mysql查询字段a的总和如果字段b =“状态”
- c# - 如何获取数组的输入并打印它?
- windows - 为什么我收到错误未绑定变量 cygwin bash 错误
- asp.net - jQuery 多个选择 Dropbox 不起作用
- google-cloud-platform - 数据流 - 状态持久性规范
- flutter - 我正在尝试使用颤振框架创建一个项目,但我不断收到此错误
- php - Mysql:请帮忙在库存系统中添加产品位置
- face-detection - 要在特定设备上使用Android camera2 api进行人脸识别,您需要将设备水平转动
- python - 我的列表中有一个字符串,应该是一个列表