2015-06-30 5 views
-1

У меня вопрос, основанный на ответе, который я видел. Он использует пул потоков для управления потоками, но каждый поток печатает 'Going to sleep... i', спит для i и затем печатает 'Slept..'. мой вопрос, почему он печатает 'Going to sleep...Going to sleep...Going to sleep...'? Он не печатает их на новой строке, если я явно не добавлю \n в конец строки. Вот мой вывод без \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!!` 

Вот мой выход с новой строки

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!! 

Промежутки между Going to sleep... и первым Slept.. показаться странным для меня, как хорошо.

Вот код

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!!" 

ответ

2

print заявления первым пишет свой текст sys.stdout, и как только то, что написано, отдельные байты-код обрабатывает запись \n символа новой строки:

>>> 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   

Примечания раздельного PRINT_ITEM и PRINT_NEWLINE байт-коды при разборке.

При использовании print в многопоточной среде вы можете в конечном итоге переключать потоки между этими двумя отдельными шагами; нити 1, 2 и 3 могут в конечном итоге записать печатное сообщение, переключить потоки, и только после того, как другой поток написал свое сообщение, это новая строка.

Добавив в ваше сообщение \n, вы убедитесь, что новая строка написана в одно и то же время. Вы действительно пишете два новые строки для sys.stdout в этом случае.

+0

так разумно думать, что вы должны использовать 'sys.stdout.write' и явно писать все' \ n' вместо использования печати, чтобы избежать этой проблемы? – SirParselot

+0

@SirParselot: вы действительно можете написать прямо в 'sys.stdout'. Учитывайте, что условия гонки могут все еще иметь место между различными вызовами 'write()'. –

+0

У вас были бы условия гонки между вызовами 'print()', хотя, верно? – SirParselot

Смежные вопросы