Python 为什么我在从不同进程读取文件时得到了竞争条件?

Python 为什么我在从不同进程读取文件时得到了竞争条件?,python,multiprocessing,Python,Multiprocessing,我正在尝试读取包含6000行相同长度的大文本文件。 文件可以通过不同的进程访问,我获取互斥以防止竞争条件。但输出包含部分读取行: 58 '444444444444444444444444444444444444444444444444444444444\n' 58 '333333333333333333333333333333333333333333333333333333333\n' 46 '444444444444444444444444442222222222222222222\n' 58

我正在尝试读取包含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()
首先,我希望将
文件
描述符复制到另一个进程时会出错,但程序已启动,所有进程都可以从该文件读取。
但竞争条件让我泄气,为什么每个进程不读取整行?

您不会因为不复制任何内容而无法复制文件对象(通常意义上)。您使用的是(Unix)默认
fork
技术,因此每个进程都继承(一个写时拷贝版本)相同的打开文件


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

请您使用
lock
作为模块中的全局变量,而不是加载程序的一部分来测试它,好吗?@Slam,相同的行为我认为问题在于缓冲,而不是锁定。每个进程从文件中读取整个块,然后从其缓冲区返回行,直到其为空,然后才从文件中读取另一个块。共享文件偏移量按块大小步进,而不是按行大小步进。希望能有所帮助,我现在没有时间写更多的简短评论。