2017-03-17 58 views
2

最近我一直在用python触摸多线程区域。下面的例子将更好地说明我的问题: 所以我有两个.py文件,一个是test.py,另一种是在test.py test2.py锁定实例不能在两个.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处理导入的一些基本知识,请原谅我的无知。

回答

3

这是Python导入系统中令人困惑的部分之一。您没有两个模块,testtest2。您有三个模块,分别为__main__,testtest2。同样,你没有一个锁,test.lock您有两个锁,__main__.locktest.lock

当您运行python test.py,巨蟒开始执行test.py__main__模块,而不是test模块。当__main__进口test2test2进口test时,Python开始运行test.py再次,这次作为test模块。 if __name__ == '__main__'以内的所有内容都会再次运行,其中包括lock = Lock(),这是第二次锁定。

__main__中,设置线程运行的两个函数是__main__.foo1test2.foo2__main__.foo1正在使用__main__.lock,而test2.foo2正在使用从test导入的test.lock。由于这些是不同的锁,所以不存在互斥。


不直接关系到你的问题,但不要叫你的模块test,因为已经有同名的标准库模块,并且不使用圆形进口。有test进口test2test2进口test会导致各种各样的讨厌的错误。

+0

非常感谢您的回答。这确实是我之前注意到的python的一部分,但从未挖掘过它,因为它不会产生问题。我会尝试测试它,然后接受你的答案。并感谢有关测试的评论。哈哈,我只是觉得这是测试一些代码的自然名称。如果我可能会问,当你测试一些代码时,你使用什么名字。 –

+0

@qichao_he:如果这只是一些快速实验,我会在5分钟内扔掉,我经常选择诸如“asdf.py”或“foo.py”之类的东西。如果我要继续研究它,我会尝试选择一些描述性的东西,比如'import_lock_test.py'。 – user2357112