Почему сценарий, использующий потоки, иногда печатает лишние строки?

Если print s заменяется на print >> sys.stderr, s , тогда эффект исчезает.

import random, sys, time
import threading

lock = threading.Lock()

def echo(s):
    time.sleep(1e-3*random.random()) # instead of threading.Timer()
    with lock:
        print s

for c in 'abc':
    threading.Thread(target=echo, args=(c,)).start()

Пример

# Run until empty line is found:
$ while ! python example.py 2>&1|tee out|grep '^$';do echo -n .;done;cat out

Выходные данные

....................
b

c
a

Выходные данные не должны содержать пустых строк, но они есть. Я понимаю, что print не является потокобезопасным, но я бы подумал, что блокировка должна помочь.

Возникает вопрос , почему это происходит?

Моя машина:

$ python -mplatform
Linux-2.6.38-11-generic-x86_64-with-Ubuntu-11.04-natty

Дополнительные строки печатаются на py26, py27, pypy.

py24, py25, py31, py32 ведут себя должным образом (без пустых строк).

Варианты

  • sys.stdout.flush () после print не решают проблему:

     с блокировкой: 
    print (s) {{ 1}} sys.stdout.flush () 
     
  • еще более странно, что обычная sys.stdout.write () не создает пустых строк с блокировкой:

     с блокировкой : 
    sys.stdout.write (s) 
    sys.stdout.write ('\ n') # ПРИМЕЧАНИЕ: no .flush () 
     
  • print функция работает должным образом (без пустых строк).

Для воспроизведения файлов загрузки и запуска:

$ tox

7
задан jfs 7 October 2011 в 17:28
поделиться