之前写过一篇用python实现多进程与多线程的文章,在使用多进程或者多线程的情况下,使用锁来实现互斥以避免同时对资源执行读和写就成为一个不可避免的事情。 对于一般的变量资源来说实现互斥锁很简单,使用
multiprocessing.Lock
类或者threading.Lock
即可。但是如果我们要实现互斥的是文件呢?
写这篇文章的初衷是我没有找到现成的库可以用,所以特意自己写了一个想贴出来。但是写到一半的时候发现了filelock
库可以解决这个问题,使用起来要比自己写的更好一些。索性就把原来写的全都删了,分享一下用filelock
实现文件锁的方法。
安装
使用pip或者conda等安装filelock即可。
1 | pip install filelock |
使用
这里将介绍一下用filelock
模块实现文件锁的基本用法。
导入接口
1 | from filelock import FileLock |
文件和锁文件
1 | file = "file.txt" |
这里的文件file
是我们要实现互斥锁定的文件。
锁文件lockfile
用于确定是否允许进程或者线程访问该文件,具体机制我们可以不必关心,能够正确创建的使用就可以了。
实例化锁对象
1 | lock = FileLock(lockfile) |
实例化出来一个锁对象lock
,注意这里的参数是锁文件lockfile
而不是文件file
。
lock
在上锁的时候,如果文件已经被其他对象上了锁,那么将一直等待到文件被其他对象释放锁后再上锁。如果不想在获取不到锁的时候永远等待下去,可以如下实例化锁对象:
1 | lock = FileLock(lockfile, timeout = 5) |
这时,lock
在上锁的时候,如果文件已经被其他对象上了锁,那么在5秒内如果文件被其他对象释放锁,lock
会对其上锁;否则就会因超时而报错退出。
锁的获取和释放
1 | lock.acquire() |
使用方法很直观,acquire()
方法用于获取锁,release()
方法用于释放锁。
完整代码
1 | from filelock import FileLock |
例子
这里,我们将分别跑两个相同的脚本main1.py
和main2.py
以模拟多进程,这两个脚本均试图排他的获取文件file.txt
。
main1.py
和main2.py
中的内容:
1 | import time |
先后将main1.py
和main2.py
跑起来,输出如下:
显然,main1.py
先完成了对文件上锁,main2.py
就一直处于等待中,一直到main1.py
释放了锁,main2.py
实现了文件上锁,从而实现了对文件的互斥性访问。