• Python多进程操作同一个文件,文件锁问题


    最近工作当中做了一个项目,这个项目主要是操作文件的。

    在操作耗时操作的时候,我们一般采用多线程或者多进程。在开发中,如果多个线程需要对文件进行读写操作,就需要用到线程锁或者是文件锁。

    使用fcntl

    在Linux下,Python的标准库有线程的文件锁,来自fcntl模块。这个模块提供了Unix系统fcntl()和ioctl()的接口。

    对于文件锁的操作,主要需要使用fcntl.flock(fd,operation)这个函数。

    其中,参数fd表示文件描述符;参数operation指定要进行的锁操作,该参数的取值有如下几种:

    • LOCK_SH:表示要穿件一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有。
    • LOCK_EX:表示创建一个排它锁,在任意时间内,一个文件的排它锁只能被一个进程拥有
    • LOCK_UN:表示删除该进程创建的锁
    • LOCK_MAND:它主要是用于共享模式强制锁,它可以与LOCK_READ或者LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作。

    我这次工作的应用场景是两个py文件操作同一个文本,所以是多进程操作文本。

    #!/usr/bin/python
    # coding:utf-8
    
    import fcntl
    import threading
    import time
    
    def writetoTxt():
        id = threading.currentThread().getName()
        with open("aaa.txt", "a") as f:
            # fcntl.flock(f.fileno(), fcntl.LOCK_EX)  # 加锁
            print("{} acquire lock".format(id))
            for i in range(10):
                f.write('"write from" + str(i) + {} 
    '.format(id))
                time.sleep(2)
        # 在with块外,文件关闭,自动解锁
        print("{} exit".format(id))
    if __name__ == '__main__':
        writetoTxt()

    执行结果:

    使用文件锁 

    没有使用文件锁

    如果从执行结果出发,我们看不出两者之间的区别,我想应该是写入内容太少了,看不出效果,有时间再研究下。

    通过执行界面,我们是可以看出两者的区别的:

    使用文件锁

    从下面两个图中,我们可以看出,file_lock1.py文件是处于阻塞状态的,但是没有退出。

     

    不使用文件锁

    说明这两个进程都不会被阻塞。

     

    注意:

    1、文件close之火,文件锁也会失效
    2、进程结束后,文件锁也会失效
    3、flock()的LOCK_EX是"劝告锁",系统内核不会强制检查锁的状态,需要在代码中进行文件操作的地方显示检查才能生效。

     相关资料:

    1.Linux中的文件锁的概念及其实现(http://blog.csdn.net/jianhong1990/article/details/26369465)

    2.fcntl模块的官方文档(https://docs.python.org/2/library/fcntl.html#fcntl.flock)

     建议:

    没事还是多看看官方文档吧,能收获很多。

  • 相关阅读:
    2月25日
    Maven启动tomcat7:run运行异常:org.apache.catalina.LifecycleException: Failed to start component
    Junit测试报错:java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    tomcat启动控制台乱码
    Java虚拟机内存详解
    Ajax使用
    Struts2工作流程
    java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
    Spring-Aop的两种代理方式
    springboot与dubbo整合遇到的坑
  • 原文地址:https://www.cnblogs.com/itpython/p/10575462.html
Copyright © 2020-2023  润新知