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

 

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

使用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) + {} \n'.format(id))
            time.sleep(2)
    # 在with块外,文件关闭,自动解锁
    print("{} exit".format(id))
if __name__ == '__main__':
    writetoTxt()

 

python 多进程 文件读写 python多进程读取同一个文件_文件锁

 

执行结果:

使用文件锁 

python 多进程 文件读写 python多进程读取同一个文件_python_02

 

没有使用文件锁

python 多进程 文件读写 python多进程读取同一个文件_python 多进程 文件读写_03

 

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

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

使用文件锁

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

python 多进程 文件读写 python多进程读取同一个文件_多进程_04

 

python 多进程 文件读写 python多进程读取同一个文件_文件锁_05

不使用文件锁

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

 

python 多进程 文件读写 python多进程读取同一个文件_多进程_06

python 多进程 文件读写 python多进程读取同一个文件_python 多进程 文件读写_07

注意:

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)

 

 建议:

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