解决Paramiko中的线程清理问题

11 投票
3 回答
7557 浏览
提问于 2025-04-15 16:04

我在使用paramiko进行自动化处理时遇到了一个错误:

Exception in thread Thread-1 (most likely raised during interpreter 
shutdown)

....
....
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 
'error' 

我知道这个问题出在清理和线程处理上,但我不知道该怎么解决。

我使用的是最新版本(1.7.6),根据这个讨论,这个问题已经解决了,所以我直接下载了代码,但还是遇到了同样的错误。

这个错误发生在Python 2.5/2.6的winxp/win2003系统上。

我在__del__这个析构函数里关闭连接,然后在脚本结束前也关闭了连接,但都没有用。使用这个方法时,错误发生得更早,所以可能和解释器的关闭没有关系??

3 个回答

1

我现在不是这个情况。不过我在找我的wxpython应用程序的问题时,发现了这个讨论。

解决办法是给主窗口添加一个关闭事件。这样所有的线程都会被关闭。

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)

        # Attributes
        self.panel = MainPanel(self)

        # Setup
        path = os.path.abspath("./comix.png")
        icon = wx.Icon(path, wx.BITMAP_TYPE_PNG)
        self.SetIcon(icon)

        # Layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panel, 1, wx.EXPAND)
        self.SetSizer(sizer)

        self.CreateStatusBar()
        # Event Handlers
        self.Bind(wx.EVT_CLOSE, self.OnClose)

   def OnClose(self, event):
        ssh.close()
        winssh.close()
        event.Skip()

希望这能对任何人有所帮助。

1

按照正常的程序流程来关闭你的连接,而不是在 __del__ 里。正如 @THC4k 所说,__del__ 不是一个析构函数,而且一般情况下,你 不应该 需要使用 __del__(当然也有例外)。

如果你自己创建线程的话,如果想让它们在主线程结束时正常退出,就需要调用 .setDaemon(True)。

7

__del__ 不是一个析构函数。它是在你删除一个对象的最后一个引用时被调用的,但这并不一定是在你退出解释器的时候发生。

任何管理上下文的东西,比如连接,都是一个 上下文管理器。比如说有一个 closing

with closing(make_connection()) as conn:
    dostuff()

# conn.close() is called by the `with`

总之,这个异常发生是因为你有一个守护线程,它还在尝试工作,而解释器已经在关闭了。

我觉得你只能通过编写代码来 在退出之前停止所有正在运行的线程 来解决这个问题。

撰写回答