title: Python多进程环境同时操作时如何互斥操作
tags: [互斥, python]
categories: [Python, 多进程]
在 Python 中,fcntl
模块提供了对文件控制操作的接口,包括文件锁定。fcntl.flock()
函数用于对文件进行锁定,以确保在多进程环境中对文件的访问是互斥的。
函数 fcntl.flock(f, operation)
中的参数解释如下:
f
是一个文件描述符,即打开文件后返回的文件对象的fileno()
方法的结果。operation
是锁定操作的类型,可以是以下几种组合:fcntl.LOCK_EX
:表示排他锁定(exclusive lock),同一时间只能有一个进程可以对文件进行写操作。fcntl.LOCK_SH
:表示共享锁定(shared lock),多个进程可以同时对文件进行读操作。fcntl.LOCK_NB
:表示非阻塞模式,如果锁定不能立即获得,函数会立即返回而不是等待。
在你提供的代码片段 fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
中,fcntl.LOCK_EX
表示尝试获取一个排他锁定,fcntl.LOCK_NB
表示如果锁定不能立即获得,则不会阻塞当前进程,函数会立即返回。
如果该调用成功,表示当前进程已经获得了排他锁定,可以安全地对文件进行写操作。如果调用失败(例如因为文件已经被其他进程锁定),则表示当前进程未能获得锁定,可以进行错误处理或重试逻辑。
请注意,使用文件锁定时,需要确保在完成文件操作后释放锁定,即使在发生异常的情况下也应该如此。可以通过调用 fcntl.flock(f, fcntl.LOCK_UN)
来释放锁定,其中 fcntl.LOCK_UN
表示解锁操作。
import fcntl
import atexit
f = open("scheduler.lock", "wb")
# noinspection PyBroadException
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
# 这里是对文件或者其他资源的写操作,不用担心其他进程会有写操作
except:
pass
def unlock():
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
atexit.register(unlock)
我的使用场景就是,使用flask启动apscheduler调度器时,wsgi指定了多个worker,导致定时任务运行多次,这里限制了单个worker启动scheduler,可以解决这个问题。
gunicorn --workers 3 --bind 0.0.0.0:5000 --access-logfile access.log --error-logfile error.log --access-logformat "{'remote_ip':'%(h)s','request_id':'%({X-Request-Id}i)s','response_code':'%(s)s','request_method':'%(m)s','request_path':'%(U)s','request_querystring':'%(q)s','request_timetaken':'%(D)s','response_length':'%(B)s'}" --log-level info --daemon wsgi:app
#乐知付 您的资源可变现平台,你管理资源,我管理密码。
书山有路勤为径,学海无涯苦作舟。
欢迎关注公众号:【程序员写书】
一起学习,一起进步。