如何实现一个线程安全函数,该函数使用键从共享哈希表中读取数据并在多线程环境中更新值?

问题描述 投票:0回答:1

假设我们有一些函数,它接受一个键,从共享哈希表中检索它的值,并对它执行一些操作以获得一个新值,然后用这个新值更新哈希表。现在,该函数是多线程的,因此可能有多个线程使用相同或不同的键调用同一函数,因此需要使用互斥体进行某种竞争条件保护。我在 python 中使用锁提出了以下实现,其中我使用字典作为哈希表。 (我知道在Python中,字典操作是原子的,但这只是为了说明算法的目的)

from threading import Lock

class Solution:
    
    def __init__(self):
        self.datamap = {}
        self.lockmap = {}
        self.datamap_lock = Lock()
        self.lockmap_lock = Lock()

    def calc(self, key, param_value):
        self.datamap_lock.acquire()
        if key not in self.datamap:
            # Create entry in hashtable if it doesnt exists
            self.datamap[key] = (-sys.maxsize, 0)
            self.datamap_lock.release()

            self.lockmap_lock.acquire()
            self.lockmap[key] = Lock()
            self.lockmap_lock.release()

        # Get the lock associated with this key
        self.lockmap_lock.acquire()
        lock = self.lockmap[key]
        self.lockmap_lock.release()

        lock.acquire()

        self.datamap_lock.acquire()
        max_, value = self.datamap[key]
        self.datamap_lock.release()

        # Does some operations on value to obtain a new value and put it back into the hash table

        self.datamap_lock.acquire()
        self.datamap[key] = (max_, value)
        self.datamap_lock.release()

        lock.release()

基本上,我对哈希表使用了一个互斥体,对每个键使用了一个互斥体,对从键映射到互斥体的哈希表使用了一个互斥体。这个实现是否正确且线程安全?有没有办法在不使用这么多锁/互斥锁的情况下做得更好?

python multithreading concurrency hashtable mutex
1个回答
0
投票
    def calc(self, key, param_value):
        self.datamap_lock.acquire()

不,请不要这样做。

更喜欢使用 上下文管理器

        with self.datamap_lock:
            ...

那么你就不会忘记释放锁了。 即使发生意外的异常。

© www.soinside.com 2019 - 2024. All rights reserved.