【问题标题】:Python filelock module behavior using `with:` statement使用 `with:` 语句的 Python 文件锁模块行为
【发布时间】:2017-06-15 04:56:23
【问题描述】:

我只是想知道 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:时文件锁是否会锁定读取访问权限?

【问题讨论】:

    标签: python multithreading with-statement file-locking filelock


    【解决方案1】:
    1. FileLock 维护一个锁计数器,该计数器在进程中的所有线程之间共享,并受到线程锁的保护。每次调用acquire() 都会增加锁计数器,并在计数器为零时额外获得操作系统级别的文件锁。同样,每次调用release() 都会减少锁定计数器并在计数器达到零时解锁文件。

      因此,如果两个线程同时获得锁,则该文件将在操作系统级别被该进程锁一次,锁计数器将增加2。两个线程不会互相阻塞。

    2. with:的重点是在其作用域退出后自动获取和释放锁。见What is the python "with" statement designed for?

    3. 文件锁用于防止当前进程之外的文件访问。它不用于线程锁定。使用常规的threading.Lock 进行线程锁定。

      # 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

    【讨论】:

      猜你喜欢
      • 2011-04-08
      • 2010-10-01
      • 2015-09-11
      • 1970-01-01
      • 2019-12-25
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      相关资源
      最近更新 更多