gpt4 book ai didi

python - 致命的 Python 错误和 `BufferedWriter`

转载 作者:IT老高 更新时间:2023-10-28 20:29:09 26 4
gpt4 key购买 nike

我在文档中看到这一段说:

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.

鉴于 GIL 正在运行,我不确定他们为什么需要“保护”他们的内部结构。谁在乎?没太在意,直到发现这个锁有一定的意义,看看这段代码:

from _thread import start_new_thread
import time

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

for i in range(10):
start_new_thread(start, ())

time.sleep(0.0001)
print("main thread exited")

在 Python 3.X 上运行时的输出:

...many SPAM...
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
main thread exited
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
SPAM SPAM SPAM!
Fatal Python error: could not acquire lock for
<_io.BufferedWritername='<stdout>'> at interpreter shutdown, possibly due to daemon threads

在 Python 2.7 下,没有错误。我不知道为什么会发生这种情况,但是,我一直在查看 bufferedio.c .另一个与上面在 Python 3.X 上测试的代码片段类似的代码,有时我得到 Fatal Python error有时我没有。任何带有循环的线程函数加上 std[out][err].write导致此 fatal error 。真的很难定义这个错误的特征,据我所知,文档没有提到任何关于它的内容。我不确定,即使它是一个错误,我希望不是。

我对这种行为的解释是这样的,*我可能完全错了:主线程在持有 sys.stdout.buffer 的锁时退出.但是,这似乎与我正在运行 Python、Linux 的系统上的主线程退出时线程终止的事实相反。


我将此作为答案发布,只是无法在评论部分完成。

这种行为不仅限于 write它影响 read以及 flush调用这些对象 BufferedReader , BufferedWriter , BufferedRandomBufferedRWPair .

1) 在 Linux 上,也可能在 Windows 上,当主线程退出时,它的子线程也会终止。这如何影响上述行为?如果主线程能够在其时间片内退出,那么在与另一个线程进行上下文切换之前,不会发生 fatal error ,因为所有线程都会终止。然而,没有什么能保证主线程一启动就会退出。

2) fatal error 发生在解释器的最终确定过程(关闭)和 read 之间。 , write , 或 flushBuffered* 上调用和可能的其他操作目的。终结过程获取那些对象的锁,任何 write例如到 BufferedWriter对象结果 Fatal Python error .

os._exit在没有完成步骤的情况下终止解释器,因此解释器不会拥有我们正在谈论的对象的锁,这是另一个例子:

from _thread import start_new_thread
import time, sys, os

def start(myId):
for i in range(10):
sys.stdout.buffer.write(b"SPAM\n")

for i in range(2):
start_new_thread(start, (i,))

x = print("main thread")
print(x)

#os._exit(0)

在上面的代码中,如果主线程一启动就退出,就是这样,不会发生 fatal error ,并且所有生成的线程都会立即终止(至少在 Linux 中),但这取决于平台。如果你很不幸,在主线程退出之前另一个线程开始在场上运行,没有 os._exit(0)调用解释器通过其正常的终结周期来获取 sys.stdout.buffer 的锁这会导致 fatal error 。多次运行此代码以注意其不同的行为。

最佳答案

当我在 windows (cygwin) 上运行第一个代码时,在 python3 上出现错误,但在 python2 上也出现错误

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

因此,在您的平台上,python2.x 可能在无法获取锁时默默地退出了线程。我也相信 _thread module (thread in 2.7) 是一个低级模块,不保证避免这种行为。来自 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.

也许你应该使用更高的级别 threading module在主线程和其他线程之间进行适当的同步。

关于python - 致命的 Python 错误和 `BufferedWriter`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45267439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com