使用套接字保持进程同步的python锁库。

socklocks的Python项目详细描述


袜子锁

这是使用套接字来实现进程间同步的概念的证明 协调跨多个进程暂停和恢复代码。

它在python 3中仅使用标准库实现。代码可以 作为更快实现的参考,例如用c或rust编写的实现。

这是贾斯汀·特纳·阿瑟写的,是根据阿帕奇许可证授权的 2、

用法

主要锁类是socketlocksocketlockthreadsafe。最喜欢 在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将在多线程锁的情况下提供更好的性能 收购不会发生。如果不确定,请使用"线程安全"选项。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
泛型Java将参数约束到公共超类   java Spring引导:在构造函数中加载属性文件并用作autowire注释   java中的优先级队列顺序错误。util。优先级队列和特定比较器   带有Java Sprint引导REST的Google应用程序引擎标准在GCLOUD服务器中不起作用   安卓从Java代码中检索变量并将其作为参数分配给TestNG   用于读取列表值的Java JSON对象   java Hibernate映射:实体映射中的重复列   多线程。start()不从Java中的父线程分派   java Android facebook webdialog网络错误(netstack:lib_mgr错误)   http使用Java阻止网站   java DynamicAsper:访问连接报表中动态列的值   java如何分离文件中的每个单词,并在表中显示每个单词和每个单词的编号?   如何打包和部署EclipseJava应用程序?   java使用Mule Anypoint,我想实现没有flowref的功能   java Kafka consumer ClassNotFoundException   java错误捕获帮助;消息不断重复   javaspring,Thymeleaf和CSS如何给错误着色   javascript如何在java中实现反向ajax   如何通过UDP连接从java数据包中读取序列号?