关于python:import静默地杀死线程

import silently kills thread

我有一个简单的程序Base.py,它测试当模块不存在时import是否能够抛出异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Base.py
import threading, os, time
import_is_working = False

class Launch(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()
    def run(self):
        global import_is_working
        try:
            print"Yes, it got into the 'try' block"
            import NON_EXISTENT_MODULE
            assert False
        except:
            print"Great, your python language is working"
            import_is_working = True
Launch()
for i in range(500):
    time.sleep(0.01)
    if import_is_working:
        break
if not import_is_working:
    print"Your import is not working."
    os._exit(4)

有时我喜欢在另一个模块Main.py中使用此代码:

1
2
# Main.py
import Base

令人惊讶的是,当我以这种方式运行它时,它不起作用:

1
2
3
4
5
6
7
max% python Base.py
Yes, it got into the 'try' block
Great, your python language is working
max% python Main.py
Yes, it got into the 'try' block
Your import is not working.
max%

这发生在Ubuntu和干净的Centos7.3安装中。


你碰到了"导入锁"。

文档提到了在线程期间导入的限制,您违反了第一个限制(强调我的限制):

While the import machinery is thread-safe, there are two key
restrictions on threaded imports due to inherent limitations in the
way that thread-safety is provided:

Firstly, other than in the main module, an import should not have the side effect of spawning a new thread and then waiting for that
thread in any way. Failing to abide by this restriction can lead to a
deadlock if the spawned thread directly or indirectly attempts to
import a module.

Secondly, all import attempts must be completed before the interpreter starts shutting itself down. This can be most easily
achieved by only performing imports from non-daemon threads created
through the threading module. Daemon threads and threads created
directly with the thread module will require some other form of
synchronization to ensure they do not attempt imports after system
shutdown has commenced. Failure to abide by this restriction will lead
to intermittent exceptions and crashes during interpreter shutdown (as
the late imports attempt to access machinery which is no longer in a
valid state).