我正在旧版 Python 应用程序中进行改造,该应用程序托管着一个(非常)大的 C++ 扩展模块。我在解释器关闭期间发生崩溃,我没有主意,所以我希望你能帮助我找出原因。
这是我迄今为止收集的信息:
- 在 Windows 上运行 Python 2.7.2(32 位);
- 由应用程序启动的所有 C++ 线程均已 (AFAICT) 关闭并正确连接;
- 应用程序启动的所有 Python 线程 (AFAICT) 均已关闭并正确加入(它们被标记为守护进程以避免作为最后手段挂起,但它们都已加入);
- Process Explorer (Sysinternals) 显示少量线程,其“起始地址”位于
ntdll.dll!TpCallbackIndependent+0x238
; - Process Explorer 显示一个线程,其“起始地址”位于
ntdll.dll!RtlMoveMemory+x5a5
; - 当应用程序退出时(成功加入所有线程后),
ntdll.dll
中的线程仍在运行,退出状态为1; - 当这种情况发生时,我所有的日志记录和诊断设施都已关闭。
这个TpCallbackIndependent
似乎与Windows Thread Pool API相关。 ,此应用程序不使用它。如果这对您有意义的话,我可以列出所有外部 Python 库,但我认为它们也没有使用它。
编辑:可能的罪魁祸首是pycurl
模块。一旦我发出第一个 pycurl.Curl.perform()
,RtlMoveMemory
和 mswsock
线程就会启动。即使我调用 pycurl.global_cleanup()
(此时 mswsock
线程消失,RtlMoveMemory
线程也永远不会完成,并且 TpCallbackIndependent
虚假地出现并在那之后永远消失。
pycurl.version
打印“libcurl/7.20.1 OpenSSL/0.9.8q zlib/1.2.5”,我不知道 pycurl
版本是什么(我只有 .pyd
文件)。
编辑:这是一个创建有问题线程的示例 Pycurl 程序。由于某种我无法解释的原因,这个特定的调用并没有崩溃......
import cStringIO
import pycurl
import sys
pycurl.global_init(pycurl.GLOBAL_DEFAULT)
try:
b = cStringIO.StringIO()
# Issue request.
c = pycurl.Curl()
try:
c.setopt(pycurl.CUSTOMREQUEST, 'GET')
c.setopt(c.URL, 'http://www.google.ca')
c.setopt(c.WRITEFUNCTION, b.write)
print 'Type anything to issue the request.'
sys.stdin.readline()
c.perform()
# Threads appear as a result of the `.perform()`
# operation. If you monitor the active threads
# in "process explorer", you see that the threads
# appear here.
finally:
c.close()
del c
finally:
print 'Type anything to cleanup.'
sys.stdin.readline()
pycurl.global_cleanup()
# If you're still looking at active threads in "process
# explorer", you see that some threads (the mswsock.dll
# thread in particular) have disappeared, but there are still
# weird TpCallbackIndependent threads showing up.
print 'Type anything to exit.'
sys.stdin.readline()
最佳答案
在调用清理之前,请确保所有 pycurl 对象都已关闭。这包括简单、共享和多对象。
关于Python 解释器在关闭时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21101055/