This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Crash when reading sys.stdin.buffer in a daemon thread
Type: crash Stage: resolved
Components: IO Versions: Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eph ​, martin.panter, socketpair, vstinner
Priority: normal Keywords:

Created on 2016-01-07 12:43 by eph ​, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg257685 - (view) Author: eph ​ (eph ​) Date: 2016-01-07 12:43
I wrote a script to non-blocking reading binary data from stdin like this:


import sys, threading

def _thread():
    data = sys.stdin.buffer.readline()

thread = threading.Thread(target=_thread)
thread.daemon = True
thread.start()


and the output is like this:


Fatal Python error: could not acquire lock for <_io.BufferedReader name='<stdin>'> at interpreter shutdown, possibly due to daemon threads

Thread 0x00007faf54ebf700 (most recent call first):
  File "pipetcpadapter.py", line 8 in func
  File "/usr/lib/python3.5/threading.py", line 862 in run
  File "/usr/lib/python3.5/threading.py", line 914 in _bootstrap_inner
  File "/usr/lib/python3.5/threading.py", line 882 in _bootstrap

Current thread 0x00007faf566da700 (most recent call first):
Aborted (core dumped)
msg257750 - (view) Author: Марк Коренберг (socketpair) * Date: 2016-01-08 11:49
16.2.4.3. Multi-threading
FileIO objects are thread-safe to the extent that the operating system calls (such as read(2) under Unix) they wrap are thread-safe too.

Binary buffered objects (instances of BufferedReader, BufferedWriter, BufferedRandom and BufferedRWPair) protect their internal structures using a lock; it is therefore safe to call them from multiple threads at once.

>>>> TextIOWrapper objects are not thread-safe. <<<<


Maybe problem here?
msg257751 - (view) Author: Марк Коренберг (socketpair) * Date: 2016-01-08 11:52
sys.stdin
sys.stdout
sys.stderr
...
These streams are regular text files....
...
msg257777 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-01-08 20:46
But sys.stdin.buffer would be a BufferedReader
msg363716 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-03-09 11:18
The problem is that Py_FinalizeEx() tries to close the sys.stdin object in _PyImport_Cleanup(), but closing the buffered object requires the object lock which is hold by _thread(). _thread() is blocked on waiting for a newline character.

I suggest to use non-blocking read in a loop, to be able to properly stop your thread at Python exit. You may want to give a try using the asyncio module.

Python works as expected. I don't see any bug here. I close the issue.
History
Date User Action Args
2022-04-11 14:58:25adminsetgithub: 70225
2020-03-09 11:18:22vstinnersetstatus: open -> closed

nosy: + vstinner
messages: + msg363716

resolution: not a bug
stage: resolved
2016-01-08 20:46:06martin.pantersetnosy: + martin.panter
messages: + msg257777
2016-01-08 11:52:34socketpairsetmessages: + msg257751
2016-01-08 11:49:23socketpairsetnosy: + socketpair
messages: + msg257750
2016-01-07 12:43:44eph ​create