当前位置:  开发笔记 > 编程语言 > 正文

如果在加载模块时使用Paramiko,为什么挂起?

如何解决《如果在加载模块时使用Paramiko,为什么挂起?》经验,为你挑选了1个好方法。

将以下内容放入一个文件hello.py(easy_install paramiko如果你还没有):

hostname,username,password='fill','these','in'
import paramiko
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(hostname=hostname, username=username, password=password)
i,o,e = c.exec_command('ls /')
print(o.read())
c.close()

适当填写第一行.

现在输入

python hello.py

你会看到一些ls输出.

现在改为输入

python

然后从解释器类型中

import hello

瞧!它挂了!如果你将代码包装在一个函数中foo,它将取消它import hello; hello.foo().

为什么Paramiko在模块初始化时使用时会挂起? Paramiko如何知道它首先在模块初始化期间被使用?



1> JimB..:

Paramiko使用单独的线程进行底层传输.你永远不应该有一个产生线程的模块作为导入的副作用.据我所知,有一个可用的导入锁,所以当你的模块中的子线程尝试另一次导入时,它可以无限期地阻塞,因为你的主线程仍然持有锁.(可能还有其他问题,我也不知道)

通常,模块在导入时不应具有任何类型的副作用,否则您将获得不可预测的结果.只是用这个__name__ == '__main__'技巧推迟执行,你会没事的.

[编辑]我似乎无法创建一个简单的测试用例来重现这个死锁.我仍然认为这是导入的线程问题,因为auth代码正在等待永远不会触发的事件.这可能是paramiko或python中的一个错误,但好消息是,如果你正确地做事,你不应该看到它;)

这是一个很好的例子,为什么你总是想要最小化副作用,以及为什么函数式编程技术变得越来越普遍.


我相信这确实是paramiko中的一个错误(或至少是缺陷).
推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有