导入 scipy.stats 后 Ctrl-C 使 Python 崩溃

2024-02-25

我在 Win7 64 位上运行 64 位 Python 2.7.3。我可以通过这样做可靠地使 Python 解释器崩溃:

>>> from scipy import stats
>>> import time
>>> time.sleep(3)

并在睡眠期间按 Control-C。不会引发键盘中断;解释器崩溃了。打印出以下内容:

forrtl: error (200): program aborting due to control-C event
Image              PC                Routine            Line        Source

libifcoremd.dll    00000000045031F8  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044FC789  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044E8583  Unknown               Unknown  Unknown
libifcoremd.dll    000000000445725D  Unknown               Unknown  Unknown
libifcoremd.dll    00000000044672A6  Unknown               Unknown  Unknown
kernel32.dll       0000000077B74AF3  Unknown               Unknown  Unknown
kernel32.dll       0000000077B3F56D  Unknown               Unknown  Unknown
ntdll.dll          0000000077C73281  Unknown               Unknown  Unknown

这使得无法中断长时间运行的 scipy 计算。

谷歌搜索“forrtl”等,我看到建议此类问题是由于使用覆盖 Ctrl-C 处理的 Fortran 库造成的。我没有在 Scipy 跟踪器上看到错误,但考虑到 Scipy 是一个与 Python 一起使用的库,我认为这是一个错误。它破坏了 Python 对 Ctrl-C 的处理。有什么解决方法吗?

编辑:按照 @cgohlke 的建议,我尝试在导入 scipy 后添加自己的处理程序。这个问题 https://gis.stackexchange.com/questions/2190/keyboardinterrupt-doesnt-work-when-arcgisscripting-module-is-loaded/2197#2197关于相关问题表明添加信号处理程序不起作用。我尝试使用 Windows API设置ConsoleCtrlHandler http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016%28v=vs.85%29.aspx通过 pywin32 函数:

from scipy import stats
import win32api
def doSaneThing(sig, func=None):
    print "Here I am"
    raise KeyboardInterrupt
win32api.SetConsoleCtrlHandler(doSaneThing, 1)

之后,按 Ctrl-C 会打印“Here I am”,但 Python 仍然因 forrtl 错误而崩溃。有时我还会收到一条消息“ConsoleCtrlHandler function failed”,但很快就消失了。

如果我在 IPython 中运行它,我可以在 forrtl 错误之前看到正常的 Python KeyboardInterrupt 回溯。如果我引发一些其他错误而不是 KeyboardInterrupt(例如 ValueError),我还会看到正常的 Python 回溯,后跟 forrtl 错误:

ValueError                                Traceback (most recent call last)
<ipython-input-1-08defde66fcb> in doSaneThing(sig, func)
      3 def doSaneThing(sig, func=None):
      4     print "Here I am"
----> 5     raise ValueError
      6 win32api.SetConsoleCtrlHandler(doSaneThing, 1)

ValueError:
forrtl: error (200): program aborting due to control-C event
[etc.]

看起来无论底层处理程序在做什么,它不仅仅是直接捕获 Ctrl-C,而是对错误条件 (ValueError) 做出反应并导致自身崩溃。有什么办法可以消除这种情况吗?


这是您发布的解决方案的一个变体,可能有效。也许有更好的方法来解决这个问题——或者甚至可以通过设置一个环境变量来告诉 DLL 跳过安装处理程序来避免这个问题。希望这对您有所帮助,直到您找到更好的方法。

这俩time module http://hg.python.org/cpython/file/70274d53c1dd/Modules/timemodule.c#l867(第 868-876 行)和_multiprocessing module http://hg.python.org/cpython/file/70274d53c1dd/Modules/_multiprocessing/multiprocessing.c#l312(第 312-321 行)调用SetConsoleCtrlHandler https://msdn.microsoft.com/en-us/library/ms686016。在这种情况下time模块,其控制台控制处理程序设置 Windows 事件,hInterruptEvent。对于主线程来说,time.sleep通过等待此事件WaitForSingleObject(hInterruptEvent, ul_millis), where ul_millis是休眠的毫秒数,除非被 Ctrl+C 中断。由于您安装的处理程序返回True, the time模块的处理程序永远不会被调用来设置hInterruptEvent, 意思是sleep不能被打断。

I tried using imp.init_builtin('time') to reinitialize the time module, but apparently SetConsoleCtrlHandler ignores the 2nd call. It seems the handler has to be removed and then reinserted. Unfortunately, the time module doesn't export a function for that. So, as a kludge, just make sure you import the time module after you install your handler. Since importing scipy also imports time, you need to pre-load libifcoremd.dll using ctypes to get the handlers in the right order. Finally, add a call to thread.interrupt_main to make sure Python's SIGINT handler gets called[1].

例如:

import os
import imp
import ctypes
import thread
import win32api

# Load the DLL manually to ensure its handler gets
# set before our handler.
basepath = imp.find_module('numpy')[1]
ctypes.CDLL(os.path.join(basepath, 'core', 'libmmd.dll'))
ctypes.CDLL(os.path.join(basepath, 'core', 'libifcoremd.dll'))

# Now set our handler for CTRL_C_EVENT. Other control event 
# types will chain to the next handler.
def handler(dwCtrlType, hook_sigint=thread.interrupt_main):
    if dwCtrlType == 0: # CTRL_C_EVENT
        hook_sigint()
        return 1 # don't chain to the next handler
    return 0 # chain to the next handler

win32api.SetConsoleCtrlHandler(handler, 1)

>>> import time
>>> from scipy import stats
>>> time.sleep(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt

[1] interrupt_main calls PyErr_SetInterrupt。这次旅行Handlers[SIGINT]并打电话Py_AddPendingCall to add checksignals_witharg。依次调用PyErr_CheckSignals. Since Handlers[SIGINT]被绊倒,这调用Handlers[SIGINT].func。最后,如果func is signal.default_int_handler,你会得到一个KeyboardInterrupt例外。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

导入 scipy.stats 后 Ctrl-C 使 Python 崩溃 的相关文章

随机推荐

  • 共享表 - 排除未作为 UIActivityType 中的类型属性提供的选项

    我想排除Add to iCloud Drive Add to Reading List Save to Files Print来自共享表 我可以使用以下代码排除 添加到阅读列表 和 打印 选项 因为这些类型属性 https develope
  • 如何实现论坛权限

    我已经开始在 MVC 框架上用 PHP 开发论坛应用程序 并且已经到了向成员分配权限的阶段 例如 读取 写入 更新 删除 现在 我知道我可以在数据库的用户表下添加 5 列并将它们设置为 1 0 但如果我想添加其他规则 例如 MOVE 这对我
  • 如何使 tkinter 窗口在 i3 windowmanager 中浮动

    我只是在 python 中玩了一下 tkinter 但是我的 i3 平铺 窗口管理器遇到了一些 麻烦 我想创建一个浮动窗口来输入值 类似于 打开文件 对话框 这一定是可能的 因为 Gimp 也可以在 i3 中使用浮动窗口 当然 我不确定 t
  • Java 中的内联比较器与自定义比较器

    对列表进行排序时 使用内联 java Comparator 带有匿名内部类 与实现单独的自定义 Comparator 类之间是否存在性能差异 1 public class SortByErrorComparator implements C
  • 如何在同一浏览器实例中运行多个测试方法而不关闭它(C#、Selenium WebDriver NUnit)?

    我是 c 和 Selenium 的初学者 我想知道是否可以在同一浏览器实例中运行多个 TestMethod s 而无需关闭它 例如 Can Change Name And Title 完成后 我想继续 Can Change Profile
  • 如何从命令行将每两行合并为一行?

    我有一个具有以下格式的文本文件 第一行是 KEY 第二行是 VALUE KEY 4048 1736 string 3 KEY 0 1772 string 1 KEY 4192 1349 string 1 KEY 7329 2407 stri
  • 调整画布图像大小

    我正在尝试上传图像并将它们放入不同大小的盒子中 为了让您了解该应用程序的功能 人们上传图像并将它们打印到海报上 例如 我们的海报尺寸为 8 x 10 活动区域 完整尺寸为 9 5 x 11 5 由于最小 DPI 为 100 我们通常将 8x
  • MTKView - 调整纹理大小以填充视图

    我对 Metal 很陌生 但正在努力遵循 Apple 的规定AVCam滤镜 https developer apple com documentation avfoundation cameras and media capture avc
  • React Native:如何正确输入嵌套导航器?

    情况 正如您可能知道的那样 我目前正在构建一个有声读物播放器 多么有创意 这是我第一个针对反应原生和打字稿的更大项目 在正确输入导航方面我有点挣扎 首先 这是一个快速概述 疑问 问题 感觉我使用了太多嵌套导航器 但由于我没有任何经验 所以很
  • Eclipse 无法运行,JVM 终止退出代码-13 [重复]

    这个问题在这里已经有答案了 大家好 无法运行 Eclipse JVM 终止 退出代码 13 我有一个问题 如图所示 当我在我的电脑中打开 Ecllipse 时出现 任何人遇到这个问题并有解决方案吗 请帮助我 提前致谢 看看这里 无法运行 E
  • Firebase 身份验证 Web:如何验证电子邮件地址

    我是 Firebase 网络身份验证新手 我设法使注册表单正常工作 但在发送电子邮件以验证用户的电子邮件地址时遇到问题 用户已正常创建并显示在我的控制台中 但未发送验证电子邮件 并且 我在 Chrome 中收到以下错误 未捕获的类型错误 无
  • 如何使用 pysftp 将字符串写入 ftp 文件?

    我有一个大的 xml 文件存储在变量中 我想使用 pysftp 将其直接写入 ftp 我相信我需要使用 pysftp putfo 这需要一个类似文件的对象 这是一个最小的例子 from io import StringIO from pys
  • Azure Functions - 使用 appsettings.json

    是否可以在 Azure Functions 中使用 appsettings json 文件 这里有环境变量的文档 https learn microsoft com en us azure azure functions functions
  • DOMDocument 简单的 GetElementsByTagName 不起作用?

    xml
  • Pandas groupby 和 qcut

    有没有一种方法可以构造 Pandas groupby 和 qcut 命令以返回具有嵌套图块的一列 具体来说 假设我有 2 组数据 并且我希望将 qcut 应用于每组 然后将输出返回到一列 这类似于允许 Partition by 的 MS S
  • 如何在部分回发时保留脚本块?

    这是我目前正在开发的网络应用程序中遇到的问题 因此 我没有用不相关的代码来混淆问题 而是在一个孤立的 简化的 Web 应用程序中重新创建了该问题 该应用程序仅演示了此问题 希望这有助于找到解决方案 我有一个网络用户控件 其内容如下
  • 从xcode中的其他目录导入文件

    我有以下目录结构 A B C D E F G 我有 A 目录 其下有 B 和 E 在 B 中 我有 C 和 D 文件 在 E 中我有 F 和 G 文件 我正在处理 G 文件 我需要导入 D 文件 我怎么做 如果我直接写 import G h
  • Rails 中的范围/named_scope 是什么?

    我最近开始实习了 我的雇主在 Rails 上使用 ruby 我经常遇到需要查找才能理解的新语法 我在谷歌上搜索了named scope的一个很好的解释 但到目前为止我发现的大部分是对它给予高度赞扬的博客文章 而不是直接的定义或介绍 ruby
  • 如何替换java字符串中的字符?

    我喜欢以有效的方式用相应的替换字符替换字符串中的某些字符 例如 String sourceCharacters String targetCharacters sdccSDCCzZ String result replaceChars Gr
  • 导入 scipy.stats 后 Ctrl-C 使 Python 崩溃

    我在 Win7 64 位上运行 64 位 Python 2 7 3 我可以通过这样做可靠地使 Python 解释器崩溃 gt gt gt from scipy import stats gt gt gt import time gt gt