我正在寻找一种算法来解决以下问题:
两个核心都在尝试使用来自多个资源池的资源。一般来说,他们不会同时使用相同的资源,但当然可能会。只有在这种情况下,一个核心应该等待另一个核心完成。否则他们可以/应该并行工作。
所以内核会做类似的事情:
lock(n);
"do something with resource n"
unlock(n);
其中n是资源的编号,并且有许多资源。
我已经实现了一些似乎有效的代码,但我真的不想重新发明轮子,而且我担心我的代码会包含一些奇怪的竞争条件,这种竞争条件会在未来的某个地方出现。有人知道是否有标准算法吗?
致以最诚挚的问候,
阿诺
答案 0 :(得分:0)
从表面上看,你似乎在问两件事:
要解决#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)
导致未定义的行为)。
如果您可以提供更好的示例,或者显示您用来解决此问题的代码,我(或其他人)可能会更好地回答您的问题。