基于值的线程锁定 [英] value based thread lock

查看:75
本文介绍了基于值的线程锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原谅我是否曾被问过.我到处走走了很多,但是我感到我没有合适的词汇量来搜索网络.

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_athread_bthread_c.每个线程可以随时通过函数foo运行.我不希望任何两个bar彼此相等的线程能够同时访问Code block ALPHA.但是,我不想阻止bar值不同的线程.在这种情况下,假设thread_a具有bar == "cat"并首先命中行(3).假设thread_a击中(5)行,假设thread_b,而bar == "cat"击中(3)行.我希望thread_b等待.但是,如果thread_cbar == "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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆