前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 实现对文件的排他读写

Python 实现对文件的排他读写

作者头像
初代庄主
发布2021-12-06 10:19:49
1.1K0
发布2021-12-06 10:19:49
举报
文章被收录于专栏:初代庄主

如果实现对同一个文件的读写,在各个进程之间互斥?

背景

默认情况下如果我们使用 open 函数来打开一个文件,另一个进程还是可以用 open 打开同一个文件。如果两个进程都向文件中写入数据的话,两个进程的数据相互覆盖(后面写的进程覆盖前面进程的数据)。这个结果通常情况下不是我们想看到的。

为了实现进程独占式的访问文件,我们需要比 open 更加低层的 API 才能实现。

解决方案

解决这个问题我们要用到两个标准库中的模块 os 和 fcntl ;其中 os 中定义了比 open 更加低层的文件访问 API `os.open`,fcntl 实现在整个操作系统层面的访问控制。只要我们程序都使用这个两个模块来访问文件,我们就能实现进程间的互斥访问。

假设我们现在要往 /tmp/a.log 文件中写入 `hello world\n`,要做到互斥访问代码可以这样写。

代码语言:javascript
复制
#!/usr/bin/env python3

import os
import time
import fcntl
import logging

logging.basicConfig(level=logging.INFO)

def exclusive_write(file:str="/tmp/a.log", content:str="hello world"):
    """
    实现对给定文件的排他写入
    
    Parameter
    ---------
    file: str
        目标文件的全路径

    content:str
        要写入内容

    """
    # 第一步 打开文件
    file_desc = os.open(file,os.O_CREAT | os.O_RDWR)

    try:
        # 第二步 加排他锁
        fcntl.lockf(file_desc,fcntl.LOCK_EX | fcntl.LOCK_NB)

        # 第三步 业务逻辑
        os.truncate(file_desc,0)
        os.write(file_desc,content.encode('utf8'));

        # 第四步 sleep 一下方便测试
        time.sleep(11)

    except IOError as err:
        logging.exception(err)

    finally:
        os.close(file_desc)
        logging.info(f"close file {file_desc}")


if __name__ == "__main__":
    exclusive_write("/tmp/a.log","hello world\n")

当第一个运行中的进程还没有退出的时候,我们再一次运行同一个程序,这个时候会报如下的错误。

代码语言:javascript
复制
python3 main.py
ERROR:root:[Errno 35] Resource temporarily unavailable
Traceback (most recent call last):
  File "/private/tmp/jss/main.py", line 27, in exclusive_write
    fcntl.lockf(file_desc,fcntl.LOCK_EX | fcntl.LOCK_NB)
BlockingIOError: [Errno 35] Resource temporarily unavailable

总结

可以看到由于加锁阶段的存在,当第二个进程申请锁的时候就直接报 BlockingIOError ,这样就实现了互斥的访问。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 初代庄主 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档