Unexpected behavior when using python thread locks and import circulation

I wrote a simple test program using thread locks. This program does not behave as expected, and the python interpreter does not complain.

test1.py:

from __future__ import with_statement
from threading import Thread, RLock
import time
import test2

lock = RLock()

class Test1(object):
    def __init__(self):
        print("Start Test1")
        self.test2 = test2.Test2()
        self.__Thread = Thread(target=self.myThread, name="thread")
        self.__Thread.daemon = True
        self.__Thread.start()
        self.test1Method()

    def test1Method(self):
        print("start test1Method")
        with lock:
            print("entered test1Method")
            time.sleep(5)
            print("end test1Method")

    def myThread(self):
        self.test2.test2Method()

if __name__ == "__main__":
    client = Test1()
    raw_input()

test2.py:

from __future__ import with_statement
import time
import test1

lock = test1.lock

class Test2(object):
    def __init__(self):
        print("Start Test2")

    def test2Method(self):
        print("start test2Method")
        with lock:
            print("entered test2Method")
            time.sleep(5)
            print("end test2Method")

Both dreams are fulfilled simultaneously! Not what I expected when using lock.

When test2Method moves to test1.py, everything works fine. When I create a lock in test2.py and import it into test1.py, everything works fine. When I create a lock in a separate source file and import it in both test1.py and test2.py, everything works fine.

This is probably due to the circulation.

But why doesn't python complain about this?

+5
source share
3 answers

Python python script $ python test1.py , test1.py __main__ test1, , , script import test1, import __main__, , , __main__.lock (test1.lock != __main__.lock).

, (, ) , , 2 script :

test1.py:

from __future__ import with_statement
from threading import Thread, RLock
import time

lock = RLock()

class Test1(object):
    def __init__(self):
        print("Start Test1")
        import test2    # <<<<<<<<<<<<<<<<<<<<<<<< Import is done here to be able to refer to __main__.lock.
        self.test2 = test2.Test2()
        self.__Thread = Thread(target=self.myThread, name="thread")
        self.__Thread.daemon = True
        self.__Thread.start()
        self.test1Method()

    def test1Method(self):
        print("start test1Method")
        with lock:
            print("entered test1Method")
            time.sleep(5)
            print("end test1Method")

    def myThread(self):
        self.test2.test2Method()

if __name__ == "__main__":
    client = Test1()
    raw_input()

test2.py:

from __future__ import with_statement
import time
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<< test1 is changed to __main__ to get the same lock as the one used in the launched script.
import __main__

lock = __main__.lock

class Test2(object):
    def __init__(self):
        print("Start Test2")

    def test2Method(self):
        print("start test2Method")
        with lock:
            print("entered test2Method")
            time.sleep(5)
            print("end test2Method")

,

+3

print import id(lock) , . , , , , test1.py __main__, test1, .

, . , , , .

  • test1 Test2

  • test1 __init__ Test2.

  • if __name__ == "__main__" test1, test1 Test2.

  • if __name__ == "__main__" Test2 , Test2 test1. ( , . , .).

:

test1.py:

class Test1(object):
    def __init__(self, lock, test2):
        print("Start Test1")
        self.lock = lock
        self.test2 = test2
        self.__Thread = Thread(target=self.myThread, name="thread")
        self.__Thread.daemon = True
        self.__Thread.start()
        self.test1Method()

    def test1Method(self):
        print("start test1Method")
        with self.lock:
            print("entered test1Method")
            time.sleep(1)
            print("end test1Method")

    def myThread(self):
        self.test2.test2Method()

if __name__ == "__main__":
    lock = RLock()
    test2 = test2.Test2(lock)
    client = Test1(lock, test2)

test2.py:

class Test2(object):
    def __init__(self, lock):
        self.lock = lock
        print("Start Test2")

    def test2Method(self):
        print("start test2Method")
        with self.lock:
            print("entered test2Method")
            time.sleep(1)
            print("end test2Method")
+1

, threading, .

? (mod1 import mod2 mod2 import mod1) :

  • mod1, (import mod1)

  • Python , sys.modules

  • import mod2, mod1 mod2

  • import mod1 mod2, mod1, sys.modules

  • ( - mod2 mod1), mod2 mod1.

4. Python test1 , sys.modules test1! , , .

, - , .

0

All Articles