Я столкнулся с проблемой, когда интерпретатор 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 (). Я не думаю, что блокировка получается извне класса в любой точке, и каждый раз, когда блокировка приобретается в классе, она выглядит как освобождаемая в окончательной ветви.
Есть ли что-то странное, что происходит здесь как часть выключения?