使用套接字保持进程同步的python锁库。
socklocks的Python项目详细描述
袜子锁
这是使用套接字来实现进程间同步的概念的证明 协调跨多个进程暂停和恢复代码。
它在python 3中仅使用标准库实现。代码可以 作为更快实现的参考,例如用c或rust编写的实现。
这是贾斯汀·特纳·阿瑟写的,是根据阿帕奇许可证授权的 2、
用法
主要锁类是socketlock
和socketlockthreadsafe
。最喜欢
在python中,实例可以用作上下文管理器,使用和
声明。
fromsocklocksimportSocketLocklock=SocketLock()withlock:print('This code will run once lock is acquired.')print('It will release the lock afterwards')
锁是专门为在多处理中使用而构建的。它们可以初始化 在进程分叉之前,然后从子进程中获取和释放。
file_lock=SocketLock()defhard_maths(increment):# Only one invocation should read/write from the file at a timewithfile_lock:withopen('number.txt','r')asf:number=int(f.read())number=math.factorial(number)+incrementwithopen('number.txt','w')asf:f.write(str(number))multiprocessing.Pool().map(hard_maths,range(5))
他们不需要叉子。可以运行多个脚本 通过提供相同的 姓名,
# script1.pywithSocketLock('critical_resource1'):do_stuff_to_res1()
# script2.pywithSocketLock('critical_resource1'):do_other_stuff_to_res1()
如果一个进程中的多个线程需要获取同一个锁,请使用
线程安全socketlockthreadsafe
使用它来解决aws lambda丢失的shm错误
aws lambda执行环境有一个需要shm的操作系统 文件系统挂载(RAM磁盘),但这种文件系统从未挂载。这个bug 通常在你需要做一些用这个 挂载,就像使用posix信号量进行进程间同步一样。
cpython的多处理和concurrent.futures模块在 这样,当操作系统试图使用shm文件为posix sempahores供电时 失败:
Traceback (most recent call last): File "/var/task/lambda_function.py", line 15, in process_things with ProcessPoolExecutor() as executor: File "/var/lang/lib/python3.6/concurrent/futures/process.py", line 390, in __init__ EXTRA_QUEUED_CALLS) File "/var/lang/lib/python3.6/multiprocessing/context.py", line 102, in Queue return Queue(maxsize, ctx=self.get_context()) File "/var/lang/lib/python3.6/multiprocessing/queues.py", line 42, in __init__ self._rlock = ctx.Lock() File "/var/lang/lib/python3.6/multiprocessing/context.py", line 67, in Lock return Lock(ctx=self.get_context()) File "/var/lang/lib/python3.6/multiprocessing/synchronize.py", line 163, in __init__ SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx) File "/var/lang/lib/python3.6/multiprocessing/synchronize.py", line 60, in __init__ unlink_now) OSError: [Errno 38] Function not implemented
为了解决这个问题,理论上你应该在 具有相应socklocks构造函数的多处理上下文:
importsocklocks# Raw multiprocessing:withsocklocks.replace_mp_context_locks(mp):mp.Pool.map(do_work,work_items)# concurrent.futures in Python 3.7+:withsocklocks.replace_mp_context_locks(mp):withconcurrent.futures.ProcessPoolExecutor(mp_context=mp)asexecutor:executor.map(do_work,work_items)
…但是,多处理队列和池也使用
多处理.boundedsemaphore
,此库不提供
替换为,因此池将不工作,只有基本锁定将。
测试
在安装了socklocks的python 3 env中的repo的本地克隆中:
pip install pytest
pytest
工作原理
任何获取锁的尝试都从尝试绑定侦听套接字开始 一个由锁的名称/id决定的地址。如果其他候选人 已经绑定到那个地址,我们假设他们有锁并且连接到 当前收单机构的监听插座。如果轮到我们去拿锁, 当前收单机构将监听套接字的套接字句柄传递给我们。一次 锁好了,我们把听筒的把手传给下一个 连接正在等待,如果没有其他人在等待,请关闭监听插座。
基于python实现和操作系统中可用的内容, 按性能从高到低的顺序,使用以下地址类型:
- Linux抽象套接字名称
- Unix域套接字路径
- 已确定IP端口上的IPv4地址127.0.0.1
套接字句柄或文件描述符使用
发送消息
在支持scm_权限
控制消息类型的posix兼容系统中。
否则,收单机构将其进程ID传递给监听器,并准备一个句柄
对于使用其他方式的新收单机构
Winsock共享套接字
导致重试操作的竞争条件
- 锁持有者可能看不到任何传入连接,并开始关闭 侦听套接字只在侦听之前有一个新的请求者连接 插座已关闭。
- 尝试连接到Unix套接字路径可能发生在 侦听套接字关闭并删除文件。
- 新的请求者可能会尝试连接到当前收单机构的listeninG 套接字之前,套接字已被置于侦听模式,导致 拒绝连接。
当使用Linux抽象套接字时,许多竞争条件都会得到缓解 因为没有要清理的文件。
已知问题
- 当前只能使用字节或与ascii兼容的字符串作为锁名称。
- 未测试Windows套接字描述符共享。告诉我进展如何。
- 当IP网络是唯一可用的基础设施时 由于使用了系统的端口范围,锁名称发生冲突的可能性 作为名称空间。
- 只实现基本锁。重入锁和信号量不是 (还没有?)是这个图书馆的一部分。
与其他锁止机构的比较
threading.lock和'u线程锁
在python标准库的线程
和线程
中找到的锁
在同步方面,模块的性能通常优于套接字锁
只有多个线程从同一进程运行的代码。要点
使用套接字是为了利用它们可以用于
进程间同步。
多处理。锁定
socketlockthreadsafe
可以用作
多处理。锁定
。如果在使用
多处理。lock
由python平台提供。非线程安全
socketlock
将在多线程锁的情况下提供更好的性能
收购不会发生。如果不确定,请使用"线程安全"选项。