基于值的线程锁定 [英] value based thread lock
问题描述
原谅我是否曾被问过.我到处走走了很多,但是我感到我没有合适的词汇量来搜索网络.
Forgive me if this has been asked before. I have looked around a lot, but I get the feeling that I don't have the proper vocabulary to find this by searching the web.
我在python中有一个多线程应用程序.我希望能够锁定特定的代码块,但只能锁定具有特定条件的其他线程.让我举个例子:有三个线程,thread_a
,thread_b
和thread_c
.每个线程可以随时通过函数foo
运行.我不希望任何两个bar
彼此相等的线程能够同时访问Code block ALPHA
.但是,我不想阻止bar
值不同的线程.在这种情况下,假设thread_a
具有bar == "cat"
并首先命中行(3)
.假设thread_a
击中(5)
行,假设thread_b
,而bar == "cat"
击中(3)
行.我希望thread_b
等待.但是,如果thread_c
与bar == "dog"
一起出现,我希望它能够继续前进.
I have a multithreaded application in python. I want to be able to lock a certain block of code but only to other threads with a certain condition. Let me give an example: There are three threads, thread_a
, thread_b
and thread_c
. Each thread may run through the function foo
at any time. I don't want any two threads with bar
equal to each other to be able to access Code block ALPHA
at the same time. However, I don't want to block threads whose bar
value is different. In this case, let's say thread_a
has a bar == "cat"
and hits line (3)
first. Before thread_a
hits line (5)
, let's say thread_b
, with bar == "cat"
hits line (3)
. I would like for thread_b
to wait. But if thread_c
comes along, with bar == "dog"
, I would like for it to be able to keep going.
(1) def foo(bar):
(2)
(3) lock(bar)
(4) # Code block ALPHA (two threads with equivalent bar should not be in here)
(5) unlock(bar)
另一个要注意的是,bar
的可能值是完全不可预测的,但是发生碰撞的可能性很高.
As another note, the possible values for bar
are completely unpredictable but with a very high chance of collision.
感谢您的帮助.我正在查看的库是 python线程库 >
Thank you for any help. The library I am looking at is the python threading library
推荐答案
已更新
好消息:我能够通过我拼凑的粗糙的测试台重现您使用原始答案遇到的release_lock
问题,并使用计数机制(根据您的建议)解决该问题-至少可以我可以用我的测试仪器告诉我.
Good news: I was able to reproduce the release_lock
problem you encountered using my original answer via a somewhat crude testbed I cobbled together, and fix the issue using a counting mechanism (as you suggested) — at least a far as I can tell with my testing apparatus.
现在使用两个单独的共享字典,一个用来像以前一样跟踪与每个锁关联的名称"或值,另一个用来跟踪在给定时间使用每个线程有多少个线程.
Now two separate shared dictionaries are used, one to keep track of the "names" or values associated with each lock as before, and another to keep track of how many threads are using each one at a given time.
像以前一样,锁名必须是可哈希值,以便它们可用作字典中的键.
As before, lock names must be hashable values so they can be used as keys in dictionaries.
import threading
namespace_lock = threading.Lock()
namespace = {}
counters = {}
def aquire_lock(value):
with namespace_lock:
if value in namespace:
counters[value] += 1
else:
namespace[value] = threading.Lock()
counters[value] = 1
namespace[value].acquire()
def release_lock(value):
with namespace_lock:
if counters[value] == 1:
del counters[value]
lock = namespace.pop(value)
else:
counters[value] -= 1
lock = namespace[value]
lock.release()
# sample usage
def foo(bar):
aquire_lock(bar)
# Code block ALPHA (two threads with equivalent bar should not be in here)
release_lock(bar)
这篇关于基于值的线程锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!