首页 文章

在代码中使用二进制信号量

提问于
浏览
0

某个计算会生成两个数组 ab
a[i]=f(i) for 0 ≤ i < n and b[i] = g(a[i]) for 0 ≤ i < n . 假设此计算被分解为两个并发进程 XY ,以便 X 计算数组 aY 计算数组 b . 这些进程使用两个二进制信号量 RS ,两者都初始化为零 . 数组 a 由两个进程共享 . 这些过程的结构如下所示 .

Process X:                         
private i;                         
for (i=0; i < n; i++) {            
    a[i] = f(i);                       
    ExitX(R, S);                       
 }                                 

Process Y:
private i;
for (i=0; i < n; i++) {
    EntryY(R, S);
    b[i]=g(a[i]);
}

以下哪一项代表 ExitXEntryY 的CORRECT实现?

(一个)

ExitX(R, S) {
    P(R);
    V(S);
}

EntryY (R, S) {
    P(S);
    V(R);
}

(B)

ExitX(R, S) {
    V(R);
    V(S);
}

EntryY(R, S) {
    P(R);
    P(S);
}

(C)

ExitX(R, S) {
    P(S);
    V(R);
}

EntryY(R, S) {
    V(S);
    P(R);
}

(d)

ExitX(R, S) {
    V(R);
    P(S);
}
EntryY(R, S) {
    V(S);
    P(R);
}

我相信答案应该是(B)因为在 X 中的临界区执行之前不应该执行进程 Y 中的临界区(首先填充 a[i] ,这必须用于 b[i] ),所以在 X 执行之后再根据选项(B)在 Y 的临界区条目中我们会找到 R=1 ,_ S=1 ,所以现在可以执行 Y 中的临界区 .

Question :正确答案是(C),我错在哪里?

2 回答

  • 2

    如果它们不是二进制信号量,'B'将起作用:在这种情况下,X可以创建一个元素,增加一个信号量,Y可以等待该信号量并使用这些项 . 信号量可以计算可用于处理的项目数 . 一个信号量就足够了 .

    但是你有二进制信号量 . 所以你只能算一个,例如X可以创建一个元素,发信号通知信号量,但是然后in不能继续创建元素,因为它不能将该信号量值提高到“2”(或更多) . 因此它必须等待Y识别该单个元素 . 并且等待引入第二个信号量,在当前元素被处理时发信号通知X.重要的是要记住,P等待信号量在必要时增加(并且V增加),因此X不能等待单个信号量返回到0,因为没有这样的操作 .

    这就是'C'正在做的事情,S实际上是'数据就绪'信号而R是'确认' . X说,它准备就绪,然后等待确认 . Y等待准备好并发送确认 .

  • 2

    首先,考虑为什么我们甚至需要两个信号量 . 原因是我们在这里有两件事要协调,

    在X循环结束之前

    • Y循环无法启动 i i
      在Y完成 i 之前
    • X循环无法启动 i+1 .

    所以有两个信号量,每个信号量管理上面的一个点 .

    信号量达到1将需要从 ExitX 调用 P . 并且 EntryY 需要调用 V . 所以B已经离开这里了 . 为了达到2,我们需要 ExitX 中的 VEntryY 中的 P .

    所以看看A,没有人会增加任何东西,所以这是一个僵局 .

    C完成这项工作 .

    D不是很正确,因为 XY 可能会在调用该信号量的任何_2390181之前两次命中 V .

相关问题