Its my understanding that when you implement a global lock in Python, this should reserve stdout for the thread that activates the lock, and therefore prevent other threads from utilizing stdout until the thread releases the lock.
Doesn't this means that in the following code, the loop in thread "a" should complete before the function in thread "b" outputs anything? When I run it, the "7" that thread "c" prints is sometimes interleaved in the output of "a".
I'd expect the output to always be the following:
5
5
5
5
5
6
7
But I am getting:
5
7
5
5
5
6
The code:
import threading, time
thelock = threading.Lock()
def afunc(var):
with thelock:
for i in range(5):
time.sleep(.0002)
print(var)
def bfunc(var):
print(var)
a=threading.Thread(target=afunc, args=(5,))
b=threading.Thread(target=bfunc, args=(6,))
c=threading.Thread(target=bfunc, args=(7,))
a.start()
b.start()
c.start()
This is with Python 3.4.3 in OS X 10.10.3. The same behavior occurs when running the file directly in the OS X Terminal, or within PyCharm 4.5.1.
You are not implementing the global lock because there is no such thing. I mean, there is but that is Global Interpreter Lock which is language feature and you are not implementing that.
GIL: http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Now, about the lock which you are implementing:
threading.Lock() - A factory function that returns a new primitive lock object. Once a thread has acquired it, subsequent attempts to acquire it block, until it is released; any thread may release it.
See official docs for threading: https://docs.python.org/2/library/threading.html
Generally speaking, when you lock some resource into critical section, this resource will be locked only for threads which must also acquire lock to access the shared resource. In your example, function b does not attempt to acquire lock before writing to stdout.
Besides, i am fairly certain that this won't work as you expect and output will be mixed up anyway, as the stdout doesn't get locked. To get clean output, you could have threads passing messages to some thread-safe shared queue, and then have only one thread write to stdout from that queue.