【问题标题】:Python threading:Is it okay to read/write multiple mutually exclusive parts of a file concurrently?Python线程:可以同时读/写文件的多个互斥部分吗?
【发布时间】:2017-07-24 15:40:47
【问题描述】:

我知道我们可以通过锁定或使用专门的线程来保证正确性,该线程的唯一工作是读/写并通过队列与之通信。

但这种方法在逻辑上似乎没问题,所以我想避免实施它们,特别是因为两者都有性能损失。

【问题讨论】:

  • 我认为如果您提供一个简短的代码示例来说明您计划如何完成它,这将有所帮助。也可以自己进行测试,看看会发生什么。
  • 它在测试中给出了正确的答案。但是,多线程程序不是以假装正确而闻名吗?

标签: python multithreading file io


【解决方案1】:

一般来说,不会。

并发读写行为严重依赖底层操作系统文件系统。

可能能够通过读取和写入既是底层块大小的倍数并且是块对齐的块来使某些东西工作。但是您很可能处于“未定义行为”的世界中。

另请参阅,相关问题:How do filesystems handle concurrent read/write?

【讨论】:

    【解决方案2】:

    OP 希望对文件进行多线程访问,而不是跨多个程序甚至网络。 因此我说YES你可以这样做。
    例如:

    def job_handler(id, job_queue):
        fh = open('test')
        while True:
            time.sleep(0.1)
            try:
                job = job_queue.get_nowait()
                # Do the job
                #   fh.read(job.offset, job.size)
                #     Work with data
                #   fh.write(job.offset, job.size)
    
            except queue.Empty:
                fh.close()
                exit(0)
    
    if __name__ == '__main__':
        job_queue = mp.Queue()
        for job in [(0, 100), (200, 100), (200, 100), (100, 100), (300, 100), (300, 100), (400, 100), (500, 100), (400, 100), (600, 100)]:
            job_queue.put( job )
    
        processes = []
        for p in range(1,4):
            processes.append( mp.Process(target = job_handler, args = (p, job_queue) ) )
    
        for p in processes:
            p.start()
            time.sleep(0.1)
    
        for p in processes:
            p.join()
    

    为了说明我对 风险 的含义,我在 job_queue 中复制了作业。 注意 [CLASH] 行,如果没有 control,进程 2 的 rw 中有进程 3 的 rw。

    输出:

    Start Job handler 1
    Start Job handler 2
    1: read offset=0
        2: read offset=200
    Start Job handler 3
            3: read offset=200
    [CLASH] offset:200 read by process:{2}
    1: write offset=0
    1: read offset=100
            3: write offset=200
        2: write offset=200
      ...
    exit(0) job_handler 3
    exit(0) job_handler 2
    exit(0) job_handler 1  
    

    结论,如果你没有这样的重复部分,你可以不用锁定。
    我建议每个进程/线程使用一个文件句柄。

    【讨论】:

    • 这与之前的答案相矛盾,不是吗?
    猜你喜欢
    • 1970-01-01
    • 2012-01-26
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多