Issue 6750: threading issue in builtins.print (original) (raw)

Bug Description

In a multi-threaded environment, the Win32 Python3000 built-in function "print" may give the output several times.

How to Reproduce:

import threading event = threading.Event() class Test(threading.Thread): def init(self, ord): super().init() self.ord = ord def run(self): event.wait() print('Hello, world!', self.ord) threads = tuple(map(Test, range(8))) tuple(map(lambda thread: thread.start(), threads)) event.set() tuple(map(lambda thread: thread.join(), threads))

EOF

Problem Observed

[The first run, 0 is doubled] Hello, world! 0 Hello, world! 0 Hello, world! 1 Hello, world! 2 Hello, world! 3 Hello, world! 4 Hello, world! 5 Hello, world! 6 Hello, world! 7

[the second run, 1 and 7 are doubled] Hello, world! 1 Hello, world! 1 Hello, world! 2 Hello, world! 3 Hello, world! 4 Hello, world! 5 Hello, world! 6 Hello, world! 7 Hello, world! 7 Hello, world! 0

Expected Result

Each thread gives ONE AND ONLY ONE output. OR State this as The Expected Behavior, document it and ask the user to write something such as critical section.

The TextIOWrapper class is not thread-safe, because it calls [the equivalent of] self.buffer.write(self.pending_bytes) before clearing self.pending_bytes. Of course the write() function will release the GIL, and another thread may send the same pending_bytes again.

Patch is attached. Antoine, can you review it?

(_pyio.TextIOWrapper does no buffering.)