python中的导入锁是什么?

python中的导入锁是什么?,python,multithreading,Python,Multithreading,我正在读《信号灯小书》,书中他有一些代码让python使用与他在书中使用的语法相似的语法。但是,当我尝试导入他的代码时,它会给我以下错误 from threading_cleanup import * RuntimeError: not holding the import lock 我知道它与watcher函数代码有关,因为如果我注释掉它,错误就会消失,那里的代码会使它消失,因此我可以使用键盘中断来结束程序 有没有办法修复这个错误 线程_.py 在我的设置中,错误仅在解释模式下发生 解释器似

我正在读《信号灯小书》,书中他有一些代码让python使用与他在书中使用的语法相似的语法。但是,当我尝试导入他的代码时,它会给我以下错误

from threading_cleanup import *
RuntimeError: not holding the import lock
我知道它与watcher函数代码有关,因为如果我注释掉它,错误就会消失,那里的代码会使它消失,因此我可以使用键盘中断来结束程序

有没有办法修复这个错误

线程_.py
在我的设置中,错误仅在解释模式下发生

解释器似乎不喜欢模块在导入fork时执行fork

如果删除
watcher()
调用,或者如果将其包装在
中,如果
中的,则错误会消失

通常,Python模块执行的代码应该只用于全局和单例的初始化

哦!!导入后,您可以从解释器调用
threading\u cleanup.watcher()
,它不会引发异常

嗯!!我意识到我没有回答你问题的标题:


调用
fork()
创建解释器的新进程;必须导入模块才能开始执行的模块。在解释模式下,您将在模块仍在导入时执行此操作,并因此锁定。在解释模式下,交互式解释器是主程序。在执行模式下,与python mymodule.py中一样,模块是主程序,因此不会被导入。这有意义吗?

此问题的标题询问导入锁是什么

导入锁是Python的
import
实现的一部分,如果您违反这些模糊的限制,就会导致程序失败:

在您的情况下,因为您直接在模块中调用
watcher()
,所以它无法启动线程,除非该模块恰好是主模块。下面是一个例子:

不过,您的示例似乎有点不同,因为它涉及流程。如果我将您的
线程\u cleanup.py
减少为:

import os
def watcher():
    child = os.fork()
watcher()
我仍然得到相同的错误:

  File "main.py", line 1, in <module>
    import threading_cleanup.py
RuntimeError: not holding the import lock
文件“main.py”,第1行,在
导入线程_cleanup.py
RuntimeError:未持有导入锁

天哪,这不是一个导入锁。除了错误消息说这是一个导入锁,不是吗?听起来像是错误消息文本中的错误。

您不能用
尝试
-
而不是键盘中断来完成程序吗?为什么要为此创建单独的流程?作为参考,我的删除答案作为注释:对我来说,这个错误发生在使用IPython时,但不是在使用普通Python解释器时。但是扎克没有使用伊皮顿,所以这不是他的原因。@ulidtko我认为这是为了让你不必在每一个程序的结尾都使用伊皮顿。由于这是一本书中的内容,大多数程序都是小程序,所以我想通过一次导入就可以更容易地解决这个问题。@Sven Marnach我使用的是适用于mac os x的32位版本的python 2.7。在默认安装的Python2.6中,代码工作得非常好,所以我想这只是我的解释器。@Zach:非常奇怪的问题。我认为值得在Python开发人员邮件列表中询问。这就是我最终所做的。(导入后调用)但是,当不在cmd行解释器上时,也会发生这种情况。这很烦人。不过这是有道理的。在python2.6中,它不会给我带来任何问题。2.7有问题。不管怎样,在导入后调用watcher似乎是一个合理的解决办法。@Zach:我想2.7在分叉后重置导入锁,以避免造成死锁:预期的行为在
多处理
模块的文档中。对于派生进程也是如此,例如。“确保新的Python解释器可以安全地导入主模块,而不会产生意外的副作用(例如启动新进程)。”-
  File "main.py", line 1, in <module>
    import threading_cleanup.py
RuntimeError: not holding the import lock