python解释器在paramiko通道__del__中挂起

时间:2018-09-18 09:21:47

标签: python python-2.7 paramiko

我遇到了一个问题,其中python解释器在关机期间挂起。我使用py-spy(https://github.com/benfred/py-spy)来收集所有挂起的线程的堆栈跟踪,并得到以下信息:

    Thread 0x7F5F2E3DB700 (idle)
    Thread 0x7F5F6416C700 (idle)
    Thread 0x7F5F6376B700 (idle)
    Thread 0x7F5F6C379700 (active)
            __bootstrap_inner (threading.py:831)
            __bootstrap (threading.py:774)
    Thread 0x7F600380A700 (active)
            accept (socket.py:206)
            accept (rpyc/utils/server.py:128)
            start (rpyc/utils/server.py:241)
            run (threading.py:754)
            __bootstrap_inner (threading.py:801)
            __bootstrap (threading.py:774)
    Thread 0x7F6025F76700 (active)
            close (paramiko/channel.py:638)
            __del__ (paramiko/channel.py:130)

我认为问题出在那些堆栈中的最后一个(我认为这可能是主线程)。

    Thread 0x7F6025F76700 (active)
            close (paramiko/channel.py:638)
            __del__ (paramiko/channel.py:130)

运行代码的服务器正在使用python2.7和paramiko 2.4.1。查看paramiko中的相关代码行,它试图在关闭通道的过程中获取一个锁:

     def close(self):
            """
            Close the channel.  All future read/write operations on the channel
            will fail.  The remote end will receive no more data (after queued data
            is flushed).  Channels are automatically closed when their `.Transport`
            is closed or when they are garbage collected.
            """
            self.lock.acquire()
            try:
                # only close the pipe when the user explicitly closes the channel.
                # otherwise they will get unpleasant surprises.  (and do it before
                # checking self.closed, since the remote host may have already
                # closed the connection.)
                if self._pipe is not None:
                    self._pipe.close()
                    self._pipe = None

                if not self.active or self.closed:
                    return
                msgs = self._close_internal()
            finally:
                self.lock.release()
            for m in msgs:
                if m is not None:
                    self.transport._send_user_message(m)

第638行是self.lock.acquire()。我认为在任何时候都不会从类外部获取该锁,并且每次在该类中获取该锁时,它似乎都将在finally分支中释放。

在关闭过程中,这里是否发生了一些奇怪的事情?

0 个答案:

没有答案