Linux:从在 docker 容器内运行的 python 脚本锁定文件

问题描述 投票:0回答:1

现状:

我正在 WAGO PFC200 PLC(定制嵌入式 Linux 固件)上运行 docker 容器。

容器运行一个 python 脚本,该脚本收集系统信息,如 CPU 负载、内存使用情况等,并将其写入 .json 文件。此过程在无限 while 循环中重复 3 秒。

该文件被写入容器文件系统“/app/out”创建的子目录,该子目录被挂载到linux文件系统的“/tmp”。

目标 从控制器上的 codesys 运行时环境中运行的程序中循环打开并读取 json 文件。

问题 打开 .json 文件时,有时 json 文件在语法上不正确。在 Codesys IDE 中测试 PLC 程序以及从 mobaXterm(FTP 文件浏览器)的文件浏览器打开文件时,会发生这种情况。然而,当我使用 NANO 在 SSH 会话中打开文件时,问题从未出现。

3 个错误文件示例:

{
    "Operating System": "Linux",
    "CPU Load": 26.0,
    "CPU Average Load (1, 5, 15 minutes)": [
        1.48828125,
        2.6689453125,
        2.6484375
    ],
    "Total RAM": 512839680,
    "Used RAM": 99794944,
    "Shared RAM": 3022848,
    "Total Swap Size": 0,
    "Available Swap Size": 0
}e": 0
}

{
    "Operating System": "Linux",
    "CPU Load": 14.9,
    "CPU Average Load (1, 5, 15 minutes)": [
        1.5234375,
        1.2978515625,
        1.8134765625
    ],
    "Total RAM": 512839680,
    "Used RAM": 96014336,
    "Shared RAM": 3035136,
    "Total Swap Size": 0,
    "Available Swap Size": 0
} 0
}

{
    "Operating System": "Linux",
    "CPU Load": 32.0,
    "CPU Average Load (1, 5, 15 minutes)": [
        1.1513671875,
        1.2685546875,
        1.265625
    ],
    "Total RAM": 512839680,
    "Used RAM": 98611200,
    "Shared RAM": 3125248,
    "Total Swap Size": 0,
    "Available Swap Size": 0
}": 0
}

*我的观察

  • 不正确的文件总是会添加 json 本身末尾的一部分(例如“e”:0 }")

  • 此错误总是伴随着较长的加载时间和加载屏幕: 在此输入图片描述

  • 打开文件时大约每 5-10 次发生一次

我的猜测

这似乎与打开和读取文件的同时写入文件有关。

我已经尝试过的

  • 将“fctnl”添加到Python脚本
def write_to_json(data, filename):
    with open(filename, 'w') as file:
        try:
            # Acquire an exclusive lock on the file
            print("Acquiring lock...")
            fcntl.flock(file, fcntl.LOCK_EX)
            print("Lock acquired.")

            # Write the system information to the file
            json.dump(data, file, indent=4)

            # Ensure data is written to disk
            file.flush()
            os.fsync(file.fileno())
        finally:
            # Release the lock
            print("Releasing lock...")
            fcntl.flock(file, fcntl.LOCK_UN)
            print("Lock released.")
  • 尝试使用 strace 记录文件上的操作

  • 尝试记录“flock”控制台命令的操作

结果

  • “调试”打印(“正在获取锁...”等)都循环出现在容器控制台中

  • 问题依然存在

  • strace只显示打开、读、写等,但不显示锁定

  • 我不能使用“auditd”代替,因为它没有安装,我无法安装新的软件包

我的问题

  • 是否有其他方法可以跟踪文件锁定操作以检查脚本的 fcntl 是否有效?

  • 它甚至可以工作吗,因为文件被写入到挂载的目录中并且Python脚本没有通过它的调用“到达”Linux文件系统?

  • 是否有其他方法可以限制同时读取和写入文件(如果这甚至是问题)?

  • 还有哪些其他原因可能导致所显示的行为?

提前感谢您的回答!

我希望我已经添加了所有必要的信息。如果您需要实际代码或其他任何内容,请告诉我。

python linux docker file-locking
1个回答
0
投票

不要就地更新文件。

写入临时文件,完成后重命名。重命名文件是一个原子操作,因此读取该文件的应用程序将始终看到一致的数据。

© www.soinside.com 2019 - 2024. All rights reserved.