Python 使用 `with:` 语句的文件锁模块行为
Python filelock module behavior using `with:` statement
我只是想知道 python 模块文件锁的细节及其在某些情况下的行为。
首先,with:
语句究竟是如何被线程处理的。如果多个线程调用 with:
是否会逐个线程锁定?有没有可能两个线程同时获取锁?
其次,当我使用with:
时,我必须在使用后清除锁吗? with:
语句执行完后锁会自动清除吗?
第三,我的代码中有一个实例,我认为必须创建一个文件然后立即将其锁定。目前我正在使用这个:
channel_file = open(os.path.join('channels', username), 'w+')
with filelock.FileLock(os.path.join('channels', username)):
channel_file.write(json.dumps({'rate': reobj.group(1),'time': reobj.group(2)}))
如果自文件创建以来另一个线程有可能读取该文件,这是否可以防止这种情况发生?
这也引出了第四点。使用 with:
时文件锁是否锁定读取访问权限?
FileLock 维护一个锁计数器,该计数器在进程中的所有线程之间共享,并受到 thread-wise 锁的保护。每次调用 acquire()
都会增加锁计数器,并且在计数器为零时额外获得 OS-level 文件锁。同样,每次调用 release()
都会减少锁定计数器并在计数器达到零时解锁文件。
因此,如果两个线程同时获取锁,则文件会在OS级别被本进程锁一次,锁计数器会增加2。两个线程不会互相阻塞。
with:
的重点是在其作用域退出后自动获取和释放锁。见 What is the python "with" statement designed for?.
文件锁用于防止当前进程之外的文件访问。它不用于 thread-wise 锁定。使用常规 threading.Lock
进行 thread-wise 锁定。
# in __main__ or somewhere before we start the threads.
channel_lock = threading.Lock()
# in the worker thread
with channel_lock:
with open(...) as channel_file:
channel_file.write(...)
有关实施细节,您可以参考 source code of py-filelock
。
我只是想知道 python 模块文件锁的细节及其在某些情况下的行为。
首先,with:
语句究竟是如何被线程处理的。如果多个线程调用 with:
是否会逐个线程锁定?有没有可能两个线程同时获取锁?
其次,当我使用with:
时,我必须在使用后清除锁吗? with:
语句执行完后锁会自动清除吗?
第三,我的代码中有一个实例,我认为必须创建一个文件然后立即将其锁定。目前我正在使用这个:
channel_file = open(os.path.join('channels', username), 'w+')
with filelock.FileLock(os.path.join('channels', username)):
channel_file.write(json.dumps({'rate': reobj.group(1),'time': reobj.group(2)}))
如果自文件创建以来另一个线程有可能读取该文件,这是否可以防止这种情况发生?
这也引出了第四点。使用 with:
时文件锁是否锁定读取访问权限?
FileLock 维护一个锁计数器,该计数器在进程中的所有线程之间共享,并受到 thread-wise 锁的保护。每次调用
acquire()
都会增加锁计数器,并且在计数器为零时额外获得 OS-level 文件锁。同样,每次调用release()
都会减少锁定计数器并在计数器达到零时解锁文件。因此,如果两个线程同时获取锁,则文件会在OS级别被本进程锁一次,锁计数器会增加2。两个线程不会互相阻塞。
with:
的重点是在其作用域退出后自动获取和释放锁。见 What is the python "with" statement designed for?.文件锁用于防止当前进程之外的文件访问。它不用于 thread-wise 锁定。使用常规
threading.Lock
进行 thread-wise 锁定。# in __main__ or somewhere before we start the threads. channel_lock = threading.Lock() # in the worker thread with channel_lock: with open(...) as channel_file: channel_file.write(...)
有关实施细节,您可以参考 source code of py-filelock
。