【发布时间】:2015-11-18 06:11:19
【问题描述】:
我们正在使用 paramiko 来创建一个连接库,该库大量使用其 get_pty 或 invoke_shell 功能。我们的库使用这些通道与目标设备进行交互。
但是每当我们使用multiprocessing 库时,我们都无法在子进程中使用 paramiko 连接句柄。 transport 在子进程中被关闭。
Is there a way to tell paramiko not to close the connection/channel at fork.
这是重现问题的示例程序
from paramiko import SSHClient, AutoAddPolicy
from multiprocessing import Process
import logging
log = logging.getLogger("paramiko.transport").setLevel(1)
client = SSHClient()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect(hostname="localhost")
def simple_work(handle):
print("==== ENTERED CHILD PROCESS =====")
stdin, stdout, stderr = handle.exec_command("ifconfig")
print(stdout.read())
print("==== EXITING CHILD PROCESS =====")
p = Process(target=simple_work, args=(client,))
p.start()
p.join(2)
print("==== MAIN PROCESS AFTER JOIN =====")
stdin, stdout, stderr = client.exec_command("ls")
print(stdout.read())
这是错误
==== ENTERED CHILD PROCESS =====
Success for unrequested channel! [??]
==== MAIN PROCESS AFTER JOIN =====
Traceback (most recent call last):
File "repro.py", line 22, in <module>
stdin, stdout, stderr = client.exec_command("ls")
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/client.py", line 401, in exec_command
chan = self._transport.open_session(timeout=timeout)
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/transport.py", line 702, in open_session
timeout=timeout)
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/transport.py", line 823, in open_channel
raise e
paramiko.ssh_exception.SSHException: Unable to open channel.
需要注意的一些重要事项
如果我尝试在子进程中访问
client。首先它根本不起作用。其次,主进程中的句柄也出人意料地死掉了。我不知道这种孩子与父母的交流是如何促进的以及为什么。
最大的问题是程序最终挂起,异常很好,但最不希望挂起。
-
如果我不在子进程中使用
李>client,而做一些其他工作,那么父进程中的client不会受到影响并且照常工作。
注意:transport.py 中有一个叫做atfork 的东西,它声称可以控制这种行为。但令人惊讶的是,即使在该方法中注释代码也没有影响。在 paramiko 的整个代码库中也没有对 atfork 的引用。
PS:我使用的是最新的 paramiko,这个程序是在 Mac 上运行的
【问题讨论】:
-
请至少添加一个触发该问题的最小示例,包括设置
logging.getLogger("paramiko.transport").setLevel(1)。 -
我很快就会这样做......
-
@tintin 我已经用代码和输出更新了问题。