Reputation: 15862
using code from this site: http://www.saltycrane.com/blog/2008/09/simplistic-python-thread-example/
The code is
import time
from threading import Thread
def myfunc(i):
print "sleeping 5 sec from thread %d" % i
time.sleep(5)
print "finished sleeping from thread %d" % i
for i in range(10):
t = Thread(target=myfunc, args=(i,))
t.start()
and I get this output:
sleeping 5 sec from thread 0
sleeping 5 sec from thread 1
sleeping 5 sec from thread 2
sleeping 5 sec from thread 3
sleeping 5 sec from thread 4
sleeping 5 sec from thread 5
sleeping 5 sec from thread 6
sleeping 5 sec from thread 7
sleeping 5 sec from thread 8
sleeping 5 sec from thread 9
finished sleeping from thread 0
finished sleeping from thread 2
finished sleeping from thread 4
finished sleeping from thread 1finished sleeping from thread 6finished sleeping from thread 8
finished sleeping from thread 5finished sleeping from thread 7finished sleeping from thread 9
finished sleeping from thread 3
what going on here? I am ok with the threads not printing in order because this is possible, but why are they not printing on newlines at the end? I am using python 2.6 under windows xp
Upvotes: 2
Views: 321
Reputation: 14989
print implemented by multiple opcodes, specifically the newline is a seperate one. Python will context switch between opcodes:
>>> def f(o):
... print o
...
...
>>> from dis import dis
>>> dis(f)
2 0 LOAD_FAST 0 (o)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Upvotes: 5
Reputation: 23145
Indeed it's not thread safe to print. In your example you might want to use the logging module. Or you could create a thread safe print.
Upvotes: 0
Reputation: 5696
You've just discovered why programming with threads is hard :)
What's happening is that all your threads are getting woken up at almost the same time. One thread starts printing out "finished sleeping from thread 1" and before it gets a chance to print that last "\n", another thread comes and prints "finished sleeping from thread 6", and on and on. Those newlines aren't being skipped, they're just moved around and bunched up elsewhere. That's probably why a line has been skipped before "finished...3". My guess is that there are many trailing blank lines that got removed due to formatting.
Use threading.Lock to put synchronization around your print
statements so that multiple print
s can't happen at the same time.
Upvotes: 6
Reputation: 1741
Because print isn't atomic a thread's print can be interrupted by another thread at any time. If thread1 is half done printing and thread2 interrupts it and starts printing, the output will be interleaved with thread1 and thread2's output.
Upvotes: 0
Reputation: 843
I think they when a thread didn't print a new line it's because the control was passed to another thread before the first thread printed the new line.
Upvotes: 2