gpt4 book ai didi

python - 多线程python访问似乎是同步的

转载 作者:太空宇宙 更新时间:2023-11-04 09:24:08 24 4
gpt4 key购买 nike

我有一个任务,其中有 10 个线程,每个线程“同时”向一个文件写入 100 行。我原以为写入会交错。相反,写入似乎是同步的。我知道 GIL,但我认为它不适用于文件 I/O,因为底层操作系统调用在 GIL 之外。

import threading
import tempfile

with tempfile.NamedTemporaryFile(delete=False) as named_temp:

temp_filename = named_temp.name
print(temp_filename)

with open(temp_filename, mode='a') as writer:

def thread_task(writer, thread_index):
for iter_index in range(0, 100):
writer.write(f'{(iter_index + thread_index * 100):06}')
writer.write('\n')

def make_thread(writer, thread_index):
return threading.Thread(target=lambda: thread_task(writer, thread_index))

threads = []
for thread_index in range(0, 10):
threads.append(make_thread(writer, thread_index))

for thread in threads:
thread.start()
for thread in threads:
thread.join()

with open(temp_filename, mode='r+') as reader:
for line in reader.readlines():
print(line, end='')

这是预料之中的,还是我设置不正确?我担心上面的代码交错输出(我不介意行的顺序但不想要像 000007000008\n\n 这样的东西。所以我打算引入锁定但是在我之前这样做我想创建一个失败的测试,但我在这样做时遇到了麻烦。

如果相关的话,这是在 Python 3.6.8 上。

此外,“写入是同步的”是指我的输出是 000001\n000002\n...000999\n 的完美顺序。至少我会期望乱序编号。

最佳答案

问题在于写入正在被缓冲,因此 GIL 实际上并未被释放(它仅在缓冲区实际写出时才被释放,这通常仅在缓冲区已满或文件明确 flushed 或 closed).由于每个线程完成的工作非常少,它们永远不会运行足够长的时间来释放 GIL,因为超时,并且由于从不实际写入磁盘,它们永远不会释放它,因为开始阻塞系统调用。

如果你让每一行都flush(或者让缓冲区足够小,一个线程在完成它的所有write之前填充它),你会看到如预期交织。一种方法是更改​​:

with open(temp_filename, mode='a') as writer:

到:

with open(temp_filename, mode='a', buffering=1) as writer:

其中 buffering=1 表示行缓冲。

关于python - 多线程python访问似乎是同步的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651750/

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