

To see the message I reduced the sleep time to 0.01 sec and increased NN to 1000. Just to add, when I inserted a lock acquire/release pair into thread1 I found that the probability of having the "unreachable" message print was greatly reduced.
#Visoft 4 k code
Thread2 = Thread(target=thread2, args=("Thread2",))Īs predicted, in running the example, the "unreachable" code sometimes is actually reached, producing output. Thread1 = Thread(target=thread1, args=("Thread1",)) # global variables are protected, task can intrude on each other. # ThreadTest01.py - Demonstrates that if non-atomic actions on With some thoughtful analysis I'm sure we could gain further insight, but for now I think it's important to demonstrate what happens when non-atomic behavior meets threading. I've organized ideas from the prior posts into a complete demonstration program (below) that I ran with Python 2.7. The thread1 if statement is not atomic, so that while that statement executes, it's possible for thread2 to intrude on thread1, allowing non-reachable code to be reached. Thanks so much Jason Pan for suggesting that method. Thread2 = Thread( target=thread2, args=("Thread-2", queue) ) Thread1 = Thread( target=thread1, args=("Thread-1", queue) ) The proper way for this kind of thing is to use Python sharing tools ( locksĪnd friends), or better, communicate data via a Queue instead of sharing it, e.g. can ALL play a role, and decide to modify the order of operations for speed, practicality or any other reason. In short: threads are complicated, and you cannot expect to have an intuitive understanding of the order in which events are happening when two (or more) threads work on the same value. And this is especially true for multithreaded programs, where you don't have any synchronization mechanism for your thread1 to know when a has been modified. In general however, you should avoid using global variables which become extremely quickly out of hand. You might get what you want with the (very frowned upon, and for good reasons) global keyword, like so: > def f(): UnboundLocalError: local variable 'a' referenced before assignment It will probably fail with a a not initialized error since the (local) a has indeed not been initialized: > a = 1 Will be interpreted by the compiler as assign to a => Create local variable a, which is not what you want.
