I've got a question based off an answer I saw. It uses a thread pool to manage threads but each thread prints 'Going to sleep... i'
, sleeps for i
time and then prints 'Slept..'
. my question is why it prints 'Going to sleep...Going to sleep...Going to sleep...'
? It doesn't print them on a newline unless I explicitly add \n
to the end of the string. Here is my output without the \n
.
`
Going to sleep...Going to sleep...Going to sleep...
Slept ..0
Going to sleep...
Slept ..1
Going to sleep...
Slept ..2
Slept ..3
Slept ..4
done!!`
Here is my output with the newline
Going to sleep...
Going to sleep...
Going to sleep...
Slept ..0
Going to sleep...
Slept ..1
Going to sleep...
Slept ..2
Slept ..3
Slept ..4
done!!
The spaces between Going to sleep...
and the first Slept..
seem strange to me as well.
Here's the code
import time
from multiprocessing.dummy import Pool
def run(i):
print "Going to sleep...\n"
time.sleep(i)
print ("Slept .." + str(i))
p = Pool(3)
res = [p.apply_async(run, (i,)) for i in range(5)]
p.close()
p.join()
print "done!!"
The print
statement first writes your text to sys.stdout
, and once that is written, a separate bytecode handles writing the \n
newline character:
>>> import dis
>>> dis.dis(compile('print "Hello world!"', '<demo>', 'exec'))
1 0 LOAD_CONST 0 ('Hello world!')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 1 (None)
8 RETURN_VALUE
Note the separate PRINT_ITEM
and PRINT_NEWLINE
bytecodes in the disassembly.
When using print
in a multi-threaded environment, you can end up switching threads between those two distinct steps; threads 1, 2 and 3 can all end up writing the printed message first, switch threads, and only after the other thread has written their message is the newline written.
By adding \n
to your message instead, you make sure that the newline is written at the same time. You really are writing two newlines to sys.stdout
in that case.