用于许多资源的细粒度锁定的算法

时间:2015-02-04 08:51:39

标签: c algorithm concurrency synchronization locking

我正在寻找一种算法来解决以下问题:

两个核心都在尝试使用来自多个资源池的资源。一般来说,他们不会同时使用相同的资源,但当然可能会。只有在这种情况下,一个核心应该等待另一个核心完成。否则他们可以/应该并行工作。

所以内核会做类似的事情:

    lock(n);
    "do something with resource n"
    unlock(n);

其中n是资源的编号,并且有许多资源。

我已经实现了一些似乎有效的代码,但我真的不想重新发明轮子,而且我担心我的代码会包含一些奇怪的竞争条件,这种竞争条件会在未来的某个地方出现。有人知道是否有标准算法吗?

致以最诚挚的问候,

阿诺

1 个答案:

答案 0 :(得分:0)

从表面上看,你似乎在问两件事:

  1. 这是一种常见的模式吗?
  2. 我做得对吗?
  3. 要解决#1,是的,这很常见,但我不知道在C中执行此操作的标准API或算法,尤其是在动态分配资源时。如果您可以预先分配资源,并且始终使用整数访问它们,您可以执行以下操作:

    #define N_RESOURCES 1024
    #define lock_resource(n) pthread_mutex_lock(&(resources[(n)].mtx))
    #define unlock_resource(n) pthread_mutex_unlock(&(resources[(n)].mtx))
    
    struct resource *resources = calloc(N_RESOURCES, sizeof (*resources));
    

    如果struct resource *不是指向您的不透明指针,并且它们是动态分配的,您可以随时执行:

    #define lock_resource(r) pthread_mutex_lock(&((r)->mtx))
    #define unlock_resource(r) pthread_mutex_unlock(&((r)->mtx))
    

    如果是不透明的指针:

    struct locked_resource {
        struct resource *r;
        pthread_mutex_t mtx;
    }
    

    并使用上述锁定策略。

    如果资源是动态的,并且您需要在分配时初始化锁定并且您无法预先分配它们,但是您可以设置您处理的资源数量的上限,则可以使用锁定向量并保持一个免费清单。您还可以使用sparse array。当然,如果资源也是同时分配的,那么在分配/销毁资源时,你必须保护你的vector / free list / lock pool。

    这可能是您试图避免的情况,此时可能值得问一下,您是否可以在排队生产者和消费者方面更好地识别您的工作模式,而是使用a non-blocking data structure

    要解决#2问题,不可能说,因为你还没有真正证明你实际在做什么。有鉴于此,我有点怀疑这是你正在寻找的那种答案。特别是,您的资源似乎可以动态分配,并且可能会在某些时候消失(可能会导致lock(n)导致未定义的行为)。

    如果您可以提供更好的示例,或者显示您用来解决此问题的代码,我(或其他人)可能会更好地回答您的问题。