2010-07-15 3 views
2

с помощью кода с этого сайта: http://www.saltycrane.com/blog/2008/09/simplistic-python-thread-example/Как выполнить потоки в python?

Код

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

и я получаю этот выход:

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 

, что здесь происходит? Я в порядке с потоками, которые не печатаются по порядку, потому что это возможно, но почему они не печатают на новых линиях в конце? Я использую python 2.6 под windows xp

ответ

2

Я думаю, что когда нить не печатала новую строку, это потому, что элемент управления был передан другому потоку, прежде чем первый поток напечатал новую строку.

+0

Думаю, вы можете быть правы. Это означает, что команда печати посылает только символ за раз. Есть 10 символов новой строки, потому что я проверил ... Странно, что меняются только символы новой строки. должно быть просто время. – Richard

+3

Это не печать одного персонажа за раз (ну, конечно, на каком-то уровне); дело в том, что поведение оператора print состоит из двух шагов: «напечатать аргумент», а затем «напечатать новую строку, если за аргументом не была запятая». Планировщик потоков Python может переключать потоки между этими двумя шагами, но он не будет переключаться посредине одного - следовательно, поведение, которое вы видите. –

0

Поскольку печать не является atomic, печать нити может быть прервана другой нитью в любое время. Если thread1 выполняется наполовину, а thread2 прерывает его и начинает печатать, выход будет чередоваться с выходом thread1 и thread2.

6

Вы только что выяснили, почему программирование потоков трудно :)

То, что происходит в том, что все ваши темы становятся разбужены в почти то же самое время. Один поток начинает печатать «завершенный сон из потока 1», и до того, как он получит возможность напечатать последний «\ n», появится еще один поток и распечатает «закончил спать из потока 6» и снова и снова. Эти новые строки не пропускаются, они просто перемещаются и сгруппированы в другом месте. Вероятно, поэтому строка была пропущена до того, как «закончил ... 3». Я предполагаю, что есть много завершающих пустых строк, которые были удалены из-за форматирования.

Используйте threading.Lock, чтобы установить синхронизацию вокруг своих операторов print, чтобы одновременно не удавалось несколько print s.

0

Действительно, печать небезопасна. В вашем примере вы можете использовать модуль регистрации. Или вы можете создать thread safe print.

5

печать осуществляется несколькими кодами операций, в частности, новая линия является отдельной. Python переключится на контекст между кодами операций:

>>> 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   
Смежные вопросы