基于值的线程锁

Phi*_*tin 7 python multithreading python-multithreading

如果之前有人问过这个问题,请原谅我。我环顾四周,但我觉得我没有合适的词汇来通过搜索网络找到它。

我在 python 中有一个多线程应用程序。我希望能够锁定某个代码块,但只能锁定具有特定条件的其他线程。让我举个例子:有三个线程,thread_athread_bthread_c。每个线程都可以foo随时运行该函数。我不希望任何两个bar彼此相等的线程能够同时访问Code block ALPHA。但是,我不想阻止bar值不同的线程。在这种情况下,假设首先thread_a有一个bar == "cat"和命中线(3)。在thread_ahits line之前(5),让我们说thread_b, with bar == "cat"hits line (3)。我愿意thread_b等待。但如果thread_c出现,与bar == "dog",我希望它能够继续前进。

(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)
Run Code Online (Sandbox Code Playgroud)

另请注意, 的可能值bar是完全不可预测的,但发生碰撞的可能性非常高。

感谢您的任何帮助。我正在查看的库是python 线程库

mar*_*eau 4

更新

\n\n

好消息:我能够release_lock通过我拼凑起来的有点粗糙的测试台使用我的原始答案重现您遇到的问题,并使用计数机制(如您所建议的) \xe2\x80\x94 至少解决问题可以用我的测试仪来判断。

\n\n

现在使用两个单独的共享字典,一个用于像以前一样跟踪与每个锁关联的“名称”或值,另一个用于跟踪在给定时间有多少线程正在使用每个锁。

\n\n

和以前一样,锁名称必须是可散列值,以便它们可以用作字典中的键。

\n\n
import threading\n\nnamespace_lock = threading.Lock()\nnamespace = {}\ncounters = {}\n\ndef aquire_lock(value):\n    with namespace_lock:\n        if value in namespace:\n            counters[value] += 1\n        else:\n            namespace[value] = threading.Lock()\n            counters[value] = 1\n\n    namespace[value].acquire()\n\ndef release_lock(value):\n    with namespace_lock:\n        if counters[value] == 1:\n            del counters[value]\n            lock = namespace.pop(value)\n        else:\n            counters[value] -= 1\n            lock = namespace[value]\n\n    lock.release()\n\n# sample usage    \ndef foo(bar):\n    aquire_lock(bar)\n    # Code block ALPHA (two threads with equivalent bar should not be in here)\n    release_lock(bar)\n
Run Code Online (Sandbox Code Playgroud)\n