You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WAGO PFC200 PLC中Docker容器Python脚本的JSON文件读写冲突排查

问题解答

1. 验证fcntl锁是否生效的替代方法

  • 手动构造并发场景:在SSH会话中运行一个脚本持续向目标文件写入测试数据,同时启动你的Python采集脚本,观察是否出现写入阻塞或内容混乱——如果锁生效,两个进程的写入操作会互斥,不会同时修改文件。
  • 增加锁状态日志:在Python脚本中,每次获取锁、释放锁时打印当前进程ID和时间戳;同时在Codesys程序中添加读取日志,或用另一个脚本模拟读取并记录时间,对比双方时间线即可判断读写是否存在重叠。
  • 检查进程文件持有状态:使用lsof -p <Python进程ID>查看脚本打开的文件描述符,确认锁对应的文件是否被正确持有;也可以用fuser -v /tmp/your-file.json实时查看哪些进程在访问目标文件。

2. 挂载目录下fcntl锁的有效性

fcntl锁是内核层面的文件描述符级锁,只要挂载的文件系统是Linux内核支持的(WAGO PFC200的/tmp一般为tmpfs,属于支持范畴),锁就会正常作用于宿主系统的文件系统。但要注意两个关键点:

  • 必须保证Python脚本对同一个文件描述符执行加锁和写入操作——如果打开文件加锁后,又重新打开文件再写入,锁会直接失效。
  • 检查挂载参数:用mount命令查看/tmp的挂载选项,只要没有nolock这类禁用文件锁的参数,就不会影响锁的生效。

3. 避免并发读写的可靠方案

  • 原子替换文件:这是最稳妥的解决方式——Python脚本先将完整的JSON数据写入临时文件(比如/app/out/temp.json),写入完成后用os.rename()原子性替换目标文件。Linux下的rename操作是原子的,读取侧只会看到完整的旧文件或新文件,绝不会读到半写入的内容。
  • 使用命名管道(FIFO):创建一个FIFO管道,Python脚本持续向管道写入数据,Codesys程序从管道读取。管道为流式结构,天然避免了文件截断或内容重叠的问题,只需处理好管道阻塞的情况即可。
  • 采用轻量内存数据库:在容器内运行一个Redis实例,Python脚本将数据写入Redis,Codesys程序通过Redis客户端读取数据——彻底绕开文件读写的并发问题,同时提升数据存取效率。
  • 临时缓解方案:将Python的写入周期(3秒)与Codesys的读取周期错开,比如让Codesys每4秒读取一次,可降低读写并发的概率,但这属于治标不治本的临时办法。

4. 其他可能导致该现象的原因

  • 文件系统缓存延迟:嵌入式系统的tmpfs缓存同步可能存在延迟,Python脚本写入数据后未立刻刷新到磁盘,导致读取时拿到缓存中的不完整数据。可在Python脚本写入完成后调用os.fsync()强制刷盘尝试解决。
  • FTP客户端的读取逻辑:MobaXterm的FTP浏览器可能采用分段读取文件的方式,当文件正在写入时,刚好读到新旧内容拼接的部分,导致末尾出现重复;而NANO是一次性将整个文件读取到内存,且可能自动添加共享锁,因此不会出现问题。
  • 嵌入式系统IO性能限制:WAGO PFC200的IO性能有限,Docker挂载目录的读写可能存在延迟,导致写入操作尚未完成就被读取。
  • Python脚本写入逻辑缺陷:比如脚本先清空文件再写入,中间存在文件为空的时间窗口;或是采用追加后截断的方式写入,导致旧内容残留。检查脚本的写入代码,确保是一次性写入完整的JSON字符串。

内容的提问来源于stack exchange,提问作者Darius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:14:54