0

(维基的问题链接:http ://en.wikipedia.org/wiki/Room_synchronization )

假设有 N 个 NODE 类型的资源,用一个数组表示

 NODE  nodearray[N];

假设有 M 个线程在起作用(读/写)。当第一个线程到达时,它可以自由选择 N 个资源中的任何一个,但只要第一个线程持有资源编号 x(x 为 0 到 n-1),第二个线程必须使用相同的 x。

假设我们要实现两个功能

int get();// gets the resource number for the thread and 
void ret();// returns the resource from the thread

任何想法/提示如何实施?

4

3 回答 3

2

对于您所说的问题,我认为您只需要保留一个计数器,指示当前正在使用哪个(单个)资源以及使所有函数调用原子化的互斥锁.

编辑:我最初在这里有代码,但它几乎与@Ajeet 在我发布此问题前几个小时在他对他自己的问题的回答中发布的代码相同。所以,如果你想要 C 中的代码,请查看@Ajeet 的答案。)

您提出的房间同步形式不是原作者所想的(链接到 pdf)。他们需要一个操作,调用者指定他们想要进入的房间。如果其他人在不同的房间,呼叫者需要等待。所以在这种情况下,我们有:

void enter(int roomnum);  // wait until everyone is out of all rooms other than roomnum
void exit(int roomnum);   // exit roomnum

并且实现更有趣。(提示:除了上面的三个变量,你还需要一个条件变量。)

如果您想知道为什么其中任何一个都没有一点用处(我想知道):在我链接到的论文中,他们正在尝试实现相对复杂的可扩展并发算法。他们提出了一种使用票自旋锁解决房间同步问题的方法(第 7 页)。并展示如何使用房间同步问题来实现可扩展的并发堆栈(第 4 页)。(并发堆栈的见解是:任意数量的线程可以使用 fetch-and-increment 同时推送,并且任意数量的线程可以同时使用 fetch-and-decrement 弹出,但是你需要确保没有同时发生推送和弹出。)

于 2013-04-07T12:15:54.633 回答
0

我有这个解决方案,但如果有人可以批评它会很棒。

int counter = 0;
int current = -1;
NODE  nodearray[N];
mutex m;

int get() {
  lock(m);
  if(!counter) {
    current = rand()%N;
  }
  ++counter;
  unlock(m);
  return current;
}

void ret() {
  lock(m);
  --counter;
  if(!counter) {
    current = -1;
  }
  unlock(m);
}
于 2013-04-07T05:38:38.920 回答
0

如果我要实现这一点。我会在所有可用资源之上创建一个包装器。您的方案就像大小为 1 的资源池。

资源池实例将是静态的,并且将在其中定义 get 和 ret 方法。此资源池实现将在调用 get 时选择一个资源,并跟踪资源是否正在使用。如果正在使用它,则将始终返回相同的实例。如果它没有被使用,那么你可以释放资源[你甚至可以在释放资源之前设置一个超时]。

内部资源池实现可以根据类的选择而有所不同,如同步器、并发哈希图等。

于 2013-04-07T05:50:06.577 回答