Richard
Richard

Reputation: 15862

How do I do threading in python?

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

Answers (5)

Alex Gaynor
Alex Gaynor

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

SiggyF
SiggyF

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

Karmastan
Karmastan

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 prints can't happen at the same time.

Upvotes: 6

shookster
shookster

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

Rivka
Rivka

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

Related Questions