Python写文件时加锁,避免写入过程中被读取

问题:

Linux上有个Python2脚本每天定时生成一些数据,并覆盖写入文件A,文件内容是每行一个Json字符串。
有一个乙方的采集器程序(类似filebeat)需要读取文件A,但发现读取的数据有截断,导致解析失败。
怀疑是因为采集器读取文件A的时候,文件A写入还未结束。

解决:

由于采集器程序是乙方自研的,属于黑箱。想着调整下Python脚本,具体方法就是增加排它锁。

在linux下,python的标准库有现成的文件锁,来自于fcntl模块。这个模块提供了unix系统fcntl()和ioctl()的接口。
对于文件锁的操作,主要需要使用 fcntl.flock(fd, operation)这个函数。
其中,参数 fd 表示文件描述符;参数 operation 指定要进行的锁操作,该参数的取值有如下几种:

  • LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有
  • LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有
  • LOCK_UN:表示删除该进程创建的锁
  • LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作
# coding: utf-8
# for python 2.x
from __future__ import unicode_literals
import codecs
import fcntl
import json
import io

# generate json_list
json_list = [{},{},{},{},{}]

with io.open("/path/to/filename", 'w+', encoding="utf8") as f:
    fcntl.flock(f.fileno(), fcntl.LOCK_EX) # 加排它锁
    for i in json_list:
        f.write(json.dumps(i, ensure_ascii=False) + "\n")
# 在with块外,文件关闭,自动解锁

参考:
Python多线程读写文件加锁

posted @ 2023-06-07 09:37  Cathon  阅读(624)  评论(0编辑  收藏  举报