在python编程中,少不了对文件的操作,那么在并发情况下,多个进程如何对同一文件进行读写操作呢?这就要用到文件锁了。
关于文件锁的的知识,需要参考UNIX环境编程,这里只简要介绍概念。python的文件锁目前使用的是fcntl这个库,它实际上为 Unix上的ioctl,flock和fcntl 函数提供了一个接口。python通过调用fcntl.flock()函数对文件加锁。
对fcntl.flock()函数的说明:
linux的flock() 的函数原型如下所示:
int flock(int fd, int operation);
其中,参数fd
表示文件描述符;参数operation
指定要进行的锁操作,该参数的取值有如下几种:
- LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有;
- LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有;
- LOCK_UN:表示删除该进程创建的锁;
- LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作;
通常情况下,如果加锁请求不能被立即满足,那么系统调用flock()会阻塞当前进程。比如,进程想要请求一个排他锁,但此时,已经由其他进程获取了这个锁,那么该进程将会被阻塞。如果想要在没有获得这个排他锁的情况下不阻塞该进程,可以将LOCK_NB 和 LOCK_SH 或者 LOCK_EX 联合使用,那么系统就不会阻塞该进程。flock()所加的锁会对整个文件起作用。
示例代码
在多个终端中启动上面的程序,会发现它们相互阻塞。
注意:
- 对于文件的 close() 操作会使文件锁失效;
- 同理,进程结束后文件锁失效;
- flock() 的 LOCK_EX是“劝告锁”,系统内核不会强制检查锁的状态,需要在代码中进行文件操作的地方显式检查才能生效。