python - 为什么在 Python 中从多个进程写入文件时我的文件没有损坏?

标签 python linux file multiprocessing python-multiprocessing

很明显,如果 write() 调用不以某种方式同步,则从多个进程写入同一个文件可能会导致数据损坏。请参阅另一个问题:Python multiprocessing safely writing to a file .

但是,在出于测试目的尝试重现此可能的错误时,我无法导致文件消息混淆。我想这样做是为了有效地比较有锁和没有锁的安全性。

什么都不做,文件似乎受到了某种保护。

import multiprocessing
import random

NUM_WORKERS = 10
LINE_SIZE = 10000
NUM_LINES = 10000

def writer(i):
    line = ("%d " % i) * LINE_SIZE + "\n"
    with open("file.txt", "a") as file:
        for _ in range(NUM_LINES):
            file.write(line)

def check(file):
    for _ in range(NUM_LINES * NUM_WORKERS):
        values = next(file).strip().split()
        assert len(values) == LINE_SIZE
        assert len(set(values)) == 1

if __name__ == "__main__":
    processes = []

    for i in range(NUM_WORKERS):
        process = multiprocessing.Process(target=writer, args=(i, ))
        processes.append(process)

    for process in processes:
        process.start()

    for process in processes:
        process.join()

    with open("file.txt", "r") as file:
        check(file)

我使用的是 Linux,我也知道文件写入可能是原子的,具体取决于缓冲区大小:Is file append atomic in UNIX? .

我试图增加消息的大小,但它并没有产生损坏的数据。

您是否知道我可以使用在 Linux 上使用多处理生成损坏文件的任何代码示例?

最佳答案

AFAIU,锁定是由内核完成的。即使您没有要求也看到锁定效果的原因是 O_NONBLOCK 文件状态标志默认未设置(我猜是在打开文件时)。

请参阅手册中关于文件状态标志的部分,尤其是参见 operating modesman 2 fcntl

我因此修补了您的示例以查看 O_NONBLOCK 的效果(事实上,断言现在确实失败了):

--- 1.py.orig   2019-07-05 14:49:13.276289018 +0300
+++ 1.py        2019-07-05 14:51:11.674727731 +0300
@@ -1,5 +1,7 @@
 import multiprocessing
 import random
+import os
+import fcntl

 NUM_WORKERS = 10
 LINE_SIZE = 10000
@@ -8,6 +10,8 @@
 def writer(i):
     line = ("%d " % i) * LINE_SIZE + "\n"
     with open("file.txt", "a") as file:
+        flag = fcntl.fcntl(file.fileno(), fcntl.F_GETFD)
+        fcntl.fcntl(file.fileno(), fcntl.F_SETFL, flag | os.O_NONBLOCK)
         for _ in range(NUM_LINES):
             file.write(line)

来源:参见thisthis (和/或 man 3p write)。

关于python - 为什么在 Python 中从多个进程写入文件时我的文件没有损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56900163/

相关文章:

从 HackerRank 确定 DNA 健康算法的 Python 实现

python - 导入前 PyCharm 打印?

python - 使用 curl 与 Python 请求

java - 在 linux 中从 c 程序调用 java 程序

python - 带条件保存文件名

Java测试磁盘是SSD还是HDD

python - Flask-RESTful API : multiple and complex endpoints

linux - 如何为 .sh 文件创建 .desktop 文件

linux - 组合条件编译参数

c - 如何用 C 编程语言将随机访问文件中的记录放入数组中?