Swi*_*ore 12 python multithreading synchronization locking
有没有办法让python锁排队?到目前为止,我一直在我的代码中假设threading.lock在队列上运行.看起来它只是锁定一个随机的锁定器.这对我不好,因为我正在工作的程序(游戏)高度依赖于以正确的顺序获取消息.python中是否有排队的锁?如果是这样,我会在处理时间上损失多少?
我完全赞同这些评论,声称你可能会以一种无用的方式思考这个问题.锁提供系列化,而不是在所有打算提供订购.执行订单的沼泽标准,简单且可靠的方法是使用aQueue.Queue
CPython将其留给操作系统来决定获取锁定的顺序.在大多数系统中,这似乎或多或少是"随机的".这无法改变.
也就是说,我将展示一种实现"FIFO锁定"的方法.这既不难也不容易 - 介于两者之间 - 你不应该使用它;-)我担心只有你能回答"我在处理时间上会损失多少?" 问题 - 我们不知道您使用锁的程度有多大,或者您的应用程序引发了多少锁竞争.但是,通过研究这段代码,您可以获得粗略的感觉.
import threading, collections
class QLock:
def __init__(self):
self.lock = threading.Lock()
self.waiters = collections.deque()
self.count = 0
def acquire(self):
self.lock.acquire()
if self.count:
new_lock = threading.Lock()
new_lock.acquire()
self.waiters.append(new_lock)
self.lock.release()
new_lock.acquire()
self.lock.acquire()
self.count += 1
self.lock.release()
def release(self):
with self.lock:
if not self.count:
raise ValueError("lock not acquired")
self.count -= 1
if self.waiters:
self.waiters.popleft().release()
def locked(self):
return self.count > 0
Run Code Online (Sandbox Code Playgroud)
这是一个小小的测试驱动程序,可以用显而易见的方式更改它QLock
或者threading.Lock
:
def work(name):
qlock.acquire()
acqorder.append(name)
from time import sleep
if 0:
qlock = threading.Lock()
else:
qlock = QLock()
qlock.acquire()
acqorder = []
ts = []
for name in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
t = threading.Thread(target=work, args=(name,))
t.start()
ts.append(t)
sleep(0.1) # probably enough time for .acquire() to run
for t in ts:
while not qlock.locked():
sleep(0) # yield time slice
qlock.release()
for t in ts:
t.join()
assert qlock.locked()
qlock.release()
assert not qlock.locked()
print "".join(acqorder)
Run Code Online (Sandbox Code Playgroud)
刚刚在我的盒子上,使用3次运行threading.Lock
产生了这个输出:
BACDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSUVWXYZT
ABCEDFGHIJKLMNOPQRSTUVWXYZ
Run Code Online (Sandbox Code Playgroud)
所以它当然不是随机的,但它也不是完全可预测的.用它QLock
来运行它,输出应始终是:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3835 次 |
最近记录: |