如何在python中创建跨线程跨进程锁?
国家: 此软件包已弃用。强烈建议使用 使用此代码库,而不是如何在python中创建跨线程跨进程锁?,python,Python,国家: 此软件包已弃用。强烈建议使用 使用此代码库,而不是紧固件\uuuu或oslo.concurrency 改用 但是,紧固件显然不是螺纹安全的: () 警告:对于单个进程中多个线程的使用情况没有任何保证 我也找不到使用oslo.concurrency的例子 还有一些建议认为,使用flock可以解决这种情况,但flock手册指出: () flock系统调用在与文件描述符fd关联的文件上应用或删除建议锁。锁是通过指定一个操作参数来应用的,该操作参数是lock_SH或lock_EX中的一个,并可选
紧固件
\uuuu或oslo.concurrency
改用
但是,紧固件
显然不是螺纹安全的:
()
警告:对于单个进程中多个线程的使用情况没有任何保证
我也找不到使用oslo.concurrency
的例子
还有一些建议认为,使用flock
可以解决这种情况,但flock手册指出:
()
flock系统调用在与文件描述符fd关联的文件上应用或删除建议锁。锁是通过指定一个操作参数来应用的,该操作参数是lock_SH或lock_EX中的一个,并可选添加lock_NB。要解锁现有锁定操作,应将其锁定
咨询锁允许协作进程对文件执行一致的操作,但不能保证一致性(即,进程仍然可以在不使用咨询锁的情况下访问文件,这可能导致不一致)
所以
下面是一个python程序,它需要在其上实现lock
和unlock
函数,以防止操作一次在一个进程实例中由多个线程执行
(提示:使用python test.py 1&python test.py 2&python test.py 3启动)
如何修复此代码以使其正常工作
import sys
import time
import random
import threading
def lock():
pass # Something here?
def unlock():
pass # Something here?
def action(i):
lock()
id = threading.current_thread()
pid = sys.argv[1]
print("\n")
for i in range(5):
print("--> %s - %s - %s " % (i, id, pid))
unlock()
class Worker(threading.Thread):
def run(self):
for i in range(10):
action(i)
for _ in range(2):
Worker().start()
当前不正确的输出如下所示:
--> 0 - <Worker(Thread-2, started 123145310715904)> - 2
--> 3 - <Worker(Thread-1, started 123145306509312)> - 1
--> 0 - <Worker(Thread-2, started 123145310715904)> - 1
--> 1 - <Worker(Thread-2, started 123145310715904)> - 2
--> 2 - <Worker(Thread-2, started 123145310715904)> - 2
--> 1 - <Worker(Thread-2, started 123145310715904)> - 1
--> 4 - <Worker(Thread-1, started 123145306509312)> - 1
-->0--2
--> 3 - - 1
--> 0 - - 1
--> 1 - - 2
--> 2 - - 2
--> 1 - - 1
--> 4 - - 1
应该看起来更像:
--> 0 - <Worker(Thread-2, started 123145310715904)> - 1
--> 1 - <Worker(Thread-2, started 123145310715904)> - 1
--> 2 - <Worker(Thread-2, started 123145310715904)> - 1
--> 3 - <Worker(Thread-2, started 123145310715904)> - 1
--> 4 - <Worker(Thread-2, started 123145310715904)> - 1
--> 0 - <Worker(Thread-2, started 123145310715904)> - 2
etc.
-->0--1
--> 1 - - 1
--> 2 - - 1
--> 3 - - 1
--> 4 - - 1
--> 0 - - 2
等
同步相关流程
如果您可以更改体系结构,从同一个父级分支出您的流程,这就足够了。例如,这会使线程连续运行:
lock = multiprocessing.Lock()
def thread_proc(lock):
with lock:
for i in xrange(0, 10):
print "IN THREAD", threading.current_thread()
time.sleep(1)
threads = [threading.Thread(
target=functools.partial(thread_proc, lock))
for i in [1, 2]
]
for thread in threads:
thread.start()
一个潜在的问题可能是,多处理.Lock
的文档记录稍微不足。我不能给您一个明确的参考,即多处理.Lock
对象也适合作为线程锁对象
这就是说:在Windows上,多处理.Lock
是使用实现的,因此您得到了一个跨进程的线程安全锁。在Unix系统上,您会得到一个具有相同属性的
可移植性也可能是一个问题,因为并非所有*NIX系统都有POSIX信号量(FreeBSD仍然有一个端口选项,可以在不支持POSIX信号量的情况下编译Python)
另请参见和Martijn Pieters的评论和
同步不相关的进程
但是,正如您在问题中所述,您有不相关的流程。在这种情况下,您需要一个命名的信号量,Python不提供现成的(尽管它实际上在幕后使用命名的信号量)
库会为您公开这些内容。似乎在所有相关平台上都能工作。不幸的是,分叉是不可能的。进程生成是在服务器内部完成的,不可修改。这适用于在另一个应用程序中运行的“用户土地”脚本posix_ipc
似乎很有希望,我会看看它是否可用,但在这种情况下我们确实必须支持OSX,而且该库上的平台限制似乎相当严重。@Doug我无法测试它,因为这里没有MAC,但如果你能在没有超时的情况下使用简单的锁,posix_ipc应该仍然适合你。但本质上,我会测试它。是的,这似乎可以在我们需要的所有平台上工作。:)