我有一个主要用 Delphi 编写的 32 位 Windows 应用程序,它使用 8087 FPU 执行 float 值模拟。我最近添加了通过 python2x.dll 使用 Python API 链接外部 Python 代码的功能。最近的这一变化导致了一些非常奇怪的行为。
该应用程序具有批处理操作模式,可以并行执行多个模拟以利用多核架构。一旦在进程中执行了 Python 代码,我就开始看到不同线程上 8087 控制字的变化。我已经非常仔细地检查了这一点,并且我观察到即使在从未调用过 Python DLL 的线程中控制字也发生了变化。
我知道这听起来很不可思议,但是,正如我所发现的,存在使这种行为显现的机制。我已经了解了信号。我首先假设 Python DLL 正在设置进程范围的信号处理程序(通过调用 signal()
)并且这些信号处理程序负责更改控制字。例如,与 Python 代码无关的线程可能会导致 SIGFPE
,而这又可能会修改控制字。
我宁愿得出 signal()
不是机制的结论。我安排在启动时执行 Python 代码。然后我将信号处理程序设置回 SIG_DFL
。然后我开始模拟。但是控制字还是发生了变化。
我的问题(最后)是是否有人知道另一种可以以这种方式更改控制字的机制。我想我正在寻找中断、APC 等!
更新
控制字被更改为 0x037F
,这是 Intel 的默认值。这不同于 0x027F
的 MSVC/Windows 默认值。我假设有东西在调用 FPINIT
。
我还发现了Py_InitializeEx
这允许调用者停止 Python 设置信号处理程序。即使我使用这种方法进行初始化,控制字也会发生变化,所以我更加确信这不是机制。
最佳答案
例如,带有DLL_THREAD_ATTACH
标志的DllMain
调用,参见msdn
更新
我找到了类似问题的链接 - DLL Load "Poisons" FPU Control Word for New Threads .但是,是的,它与 Dll 加载后创建的线程有关。
关于python - 什么可以在我背后改变我的浮点控制字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7687673/