python - 为什么我在从不同进程读取文件时出现竞争条件?

标签 python multiprocessing

我正在尝试读取包含 6000 行相同长度的大文本文件。 可以通过不同的进程访问文件,并且我获取互斥量以防止竞争条件。但是输出包含部分读取的行:

58 '444444444444444444444444444444444444444444444444444444444\n'
58 '333333333333333333333333333333333333333333333333333333333\n'
46 '444444444444444444444444442222222222222222222\n'
58 '444444444444444444444444444444444444444444444444444444444\n'

我尝试运行的代码:

import multiprocessing as mp

class Loader:
    def __init__(self, path):
        self.lock = mp.Lock()
        self.file = open(path, 'r')

    def read(self):
        with self.lock:
            try:
                line = next(self.file)
                print(len(line), repr(line))
            except StopIteration:
                return False
        return True


def worker(loader):
    while loader.read():
        pass

if __name__ == '__main__':
    loader = Loader('./data.txt')

    workers = []
    for i in range(4):
        w = mp.Process(target=worker, args=(loader,))
        w.daemon = True
        w.start()
        workers.append(w)

    for w in workers:
        w.join()

首先,我预计在将 file 描述符复制到另一个进程时会出错,但是程序已启动并且所有进程都可以从该文件中读取。 但是竞争条件让我很沮丧,为什么每个进程都不读取整行?

最佳答案

你复制一个文件对象不会失败,因为你没有复制任何东西(通常意义上)。您正在使用 (Unix) 默认的 fork 技术,因此每个进程都继承(写入时复制版本)相同的打开文件。

因此(正如 VPfB 指出的那样)每个进程都有自己的缓冲,但底层的打开文件描述是共享的,并且包含文件偏移量。如果您在开始进程之前读取一个字符,您会发现它们在发散(和混淆行)之前都报告了相同的文件前缀。

关于python - 为什么我在从不同进程读取文件时出现竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54171752/

相关文章:

python - 有没有办法将 python argparse 与 nargs ='*' 、选项和默认值一起使用?

python - 将接受类成员函数作为变量的函数传递给python multiprocess pool.map()

python - python中,如果os.chdir = 'path'已经实现,如何恢复os.chdir()的功能

python - 将 HTML 插入 Flask 的正确方法

用于并行进程的 Python 多处理

Python:Multiprocessing Queue.put 不适用于半大数据

python - 在 multiprocessing.Process() 中调用 subprocess.Popen() 时管道损坏

基于 Python 多处理的 WSGI 网络服务器

python - 无需循环即可替换 Pandas 列中的多个值

python - 线程实时记录