程序无法退出。如何查找Python正在做什么?

6 投票
5 回答
21056 浏览
提问于 2025-04-17 00:20

我有一个Python脚本,目前运行得很好。不过,我发现我的程序没有正常退出。我可以调试到最后,但程序还是一直在运行。

main.main()这个函数做了很多事情:它从数据提供者那里下载一些CSV文件(支持http、ftp、sftp等),把数据转换成标准格式,然后把所有内容加载到数据库里。

这一切都运行得很顺利。但是,程序就是不退出。我该怎么找出程序在哪里“等待”呢?

有多个数据提供者,这个脚本对所有提供者都能正常结束,只有一个(sftp下载,我用的是paramiko)不行。

if __name__ == "__main__":

    main.log = main.log2both
    filestoconvert = []
    #filestoconvert = glob.glob(r'C:\Data\Feed\ProviderName\download\*.csv')
    main.main(['ProviderName'], ['download', 'convert', 'load'], filestoconvert)

我很乐意听听大家的想法和建议!

5 个回答

2

你最好使用 GDB,它可以帮助你找到卡住的程序,就像Java中的jstack一样。

3

这个问题虽然已经有10年了,但我还是想分享我的解决方案,希望能帮助到遇到类似问题的人,尤其是那些Python脚本一直不结束的情况。

在我的情况下,调试过程并没有什么帮助。所有的调试输出只显示了一个线程。但是@JC Plessis的建议让我意识到,可能还有其他工作在进行,这让我找到了问题的根源。

我当时在用Selenium和Chrome驱动,关闭唯一打开的标签页后,我就结束了selenium的进程,代码是这样的:

driver.close()

但后来,我把代码改成了使用无头浏览器(也就是没有界面的浏览器),结果在调用driver.close()后,Selenium驱动并没有关闭,导致Python脚本一直卡在那里。经过查找,我发现正确关闭Selenium驱动的方法其实是:

driver.quit()

这样做后,问题就解决了,脚本终于又能正常结束了。

15

如果你的程序没有结束,最有可能的原因是还有一个线程在运行。

要查看所有正在运行的线程,你可以使用:

threading.enumerate()

这个函数会列出所有当前正在运行的线程(详细信息可以查看文档)。

如果这还不够,你可能需要写一点脚本来配合这个函数(详细信息可以查看文档):

sys._current_frames()

所以,要打印所有活跃线程的堆栈信息,你可以这样做:

import sys, traceback, threading
thread_names = {t.ident: t.name for t in threading.enumerate()}
for thread_id, frame in sys._current_frames().iteritems():
    print("Thread %s:" % thread_names.get(thread_id, thread_id))
    traceback.print_stack(frame)
    print()

祝你好运!

撰写回答