异步python的快速读写子树锁定
treelock的Python项目详细描述
树篱
Asyncio Python的快速读/写子树锁定。适用于大型树,当它不可行或不希望有整个树在记忆中。
灵感来自Ritik Malhotra的作品。
安装
pip install treelock
用法
TreeLock
的每个实例都是可调用的,并返回一个异步上下文管理器。为了获取iterableread_roots
中具有根节点的子树的读(共享)锁;以及获取iterablewrite_roots
中具有根节点的子树的写(独占)锁,必须将它们传递给TreeLock
:
fromtreelockimportTreeLocklock=TreeLock()asyncdefaccess(read_roots,write_roots):asyncwithlock(read=read_roots,write=write_roots):# access the sub-trees
锁是not重入者:同一个任务试图进入具有不兼容子树的多个上下文管理器将死锁。因此,所有需要的子树的锁必须预先申请。
典型的用例是对文件系统层次结构中的路径进行读/写(共享/独占)锁定。例如,如果将s3视为文件系统,但允许对文件夹执行非原子操作。
例如,可以在某些path的文件夹上定义delete
、write
、rename
、copy
和read
操作,例如PurePosixPath
的实例。这样一个路径的读锁应该允许读取相应的文件夹,但阻止所有可能更改它的操作。写锁应该阻止对该文件夹的所有其他访问。您可以使用TreeLock
来执行此操作,注意每个路径实际上是所有可能路径树中的一个节点。
fromtreelockimportTreeLocklock=TreeLock()asyncdefdelete(path):asyncwithlock(read=[],write=[path]):...asyncdefwrite(path,...):asyncwithlock(read=[],write=[path]):...asyncdefrename(path_from,path_to):asyncwithlock(read=[],write=[path_from,path_to]):...asyncdefcopy(path_from,path_to):asyncwithlock(read=[path_from],write=[path_to]):...asyncdefread(path):asyncwithlock(read=[path],write=[]):...
在https://charemza.name/blog/posts/python/asyncio/s3-path-locking/有更多关于这种用法的信息,以及底层算法的详细信息。
节点的必需属性
这些是PurePosixPath属性的子集。
每个定义了
__cmp__
和__hash__
方法。它们在内部用于字典,因此__hash__
必须足够合理,以实现恒定的时间行为。每个方法都必须定义
__lt__
方法。这必须表现良好,即定义所有可能节点之间的总顺序,否则会发生死锁。每个节点都有一个属性
parents
,它是节点的祖先的迭代器,按照__lt__
的顺序递减。这是一个命名有点错误的属性,但这与pureposixpath是一致的。
请注意,节点不需要知道其子节点。这使得TreeLock
适合在不知道节点的后代的情况下锁定节点下的子树。
快速锁定和解锁
锁定或解锁节点的操作数仅取决于节点的祖先。具体来说,它不会随着子代数量的增加而增加,也不会随着当前持有的锁的数量而增加。
运行测试
python setup.py test