最近我一直在用python触摸多线程区域。以下示例将更好地说明我的问题: 所以我有两个.py文件,一个是test.py,另一个是test2.py
在test.py中:
import time
from datetime import datetime
from threading import Thread, Lock
lock = Lock()
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(threadName)s %(name)s.%(funcName)s [%(levelname)s]: %(message)s')
def foo1():
while True:
with lock:
logging.info(datetime.now())
time.sleep(0.2)
if __name__ == '__main__':
from test2 import foo2
Thread(target=foo1).start()
Thread(target=foo2).start()
在test2.py中:
import time
from datetime import datetime
from test import logging, lock
def foo2():
while True:
with lock:
logging.info( datetime.now() )
time.sleep(5)
输出:
2017-03-17 17:11:06,210 Thread-1 root.foo1 [INFO]: 2017-03-17 17:11:06.210000
2017-03-17 17:11:06,210 Thread-2 root.foo2 [INFO]: 2017-03-17 17:11:06.210000
2017-03-17 17:11:06,415 Thread-1 root.foo1 [INFO]: 2017-03-17 17:11:06.416000
2017-03-17 17:11:06,619 Thread-1 root.foo1 [INFO]: 2017-03-17 17:11:06.620000
所以,锁似乎没有效果。我测试了如果我把foo1和foo2放在同一个.py文件中,它会起作用。
有人可以告诉我为什么吗?
我知道这可能涉及python如何处理导入的一些基本知识,请原谅我的无知。
答案 0 :(得分:4)
这是Python导入系统真正令人困惑的部分之一。您没有两个模块test
和test2
。您有三个模块__main__
,test
和test2
。同样,您没有一个锁test.lock
。 您有两个锁,__main__.lock
和test.lock
。
当您运行python test.py
时,Python开始执行test.py
作为__main__
模块,而不是test
模块。当__main__
导入test2
和test2
导入test
时,Python会再次开始运行test.py
,这次是{{1}模块。 <{1}}内的所有内容都会再次运行,包括test
,再次锁定。
在if __name__ == '__main__'
中,您设置线程运行的两个函数是lock = Lock()
和__main__
。 __main__.foo1
正在使用test2.foo2
,而__main__.foo1
正在使用从__main__.lock
导入的test2.foo2
。由于这些是不同的锁,因此没有相互排斥。
与您的问题没有直接关系,但请勿调用您的模块test.lock
,因为该名称已经是标准库模块,并且不使用循环导入。 test
导入test
和test
导入test2
会导致各种令人讨厌的错误。