Fatal Python error and `BufferedWriter`

[亡魂溺海] 提交于 2019-12-03 01:19:43

TL;DR

Your issue is not strictly related to lock stuff, but with the fact you are trying to write to a no-more-existent stdout with a daemon thread.

A bit of explain

When you run your main script the Python interpreter starts and execute your code opening the stdout file descriptor.

When your script ends without waiting for threads to finish:

  • all the threads switch from non-daemons to daemons
  • the interpreter exits calling a finalize function which wypes the threads' globals including the stdout
  • the now-daemon threads try to aquire lock for stdout which is no more accessible due to the previous step

To avoid this issue you could write to file instead of stdout (as a daemon thread should do) or just wait for threads to finish with something like:

from threading import Thread
import time

def start():
    for i in range(10):
        print("SPAM SPAM SPAM!")

# create a thread list (you'll need it later)
threads = [Thread(target=start, args=()) for i in range(10)]

# start all the threads
for t in threads:
    t.start()
# or [t.start() for t in threads] if you prefer the inlines

time.sleep(0.0001)

# wait for threads to finish
for t in threads:
    t.join()
# or [t.join() for t in threads] for the inline version

print("main thread exited")

When I ran the first code on windows (cygwin), I got the error on python3, but I also got an error on python2

> Unhandled exception in thread started by 
> sys.excepthook is missing
> lost sys.stderr

So it is possible that on your platform python2.x may have silently exited the threads when they fail to acquire the lock. Also I believe that _thread module (thread in 2.7) is a low-level module and does not guarantee to avoid this behavior. From the module help

  • When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing try ... finally clauses or executing object destructors.
  • When the main thread exits, it does not do any of its usual cleanup (except that try ... finally clauses are honored), and the standard I/O files are not flushed.

May be you should use higher level threading module with proper synchronization between main and other threads.

I think you just have an erroneous understanding of GIL.

please think about when you have GIL and a list,then manipulate the list in different threads,what will happen?if you still confuse,test it.so does the BufferedWriter.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!