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

Operating system 在代码中使用二进制信号量,operating-system,semaphore,binary-semaphore,Operating System,Semaphore,Binary Semaphore,某个计算生成两个数组A和b,这样 a[i]=f(i)表示0≤ 对于0,i代码>和 y>代码>在调用该信号量的任何 p < /代码>之前,两次都会碰到 v>代码>。 首先,考虑为什么这里我们甚至需要两个信号量。原因是我们有两件事要协调 在X循环完成之前,Y循环无法启动i 在Y结束之前,X循环无法启动i+1 因此有两个信号量,每个信号量管理上面的一点 信号量达到1将需要从ExitX调用p。而EntryY需要调用V。B已经走了。要实现2,我们需要ExitX中的V和EntryY中的P 看看A,没有人增加

某个计算生成两个数组
A
b
,这样
a[i]=f(i)表示0≤ 对于0,i
。假设此计算分解为两个并发进程
X
Y
,这样
X
计算数组
a
Y
计算数组
b
。进程使用两个二进制信号量
R
S
,都初始化为零。数组
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]);
}
(B)

(C)

(D)

我认为答案应该是(B),因为在执行
X
中的关键部分之前,进程
Y
中的关键部分不应该执行(
a[I]
首先被填充,这将必须用于
B[I]
),所以在执行
X
之后,根据选项(B)执行在输入
Y
中的关键部分时,我们将发现
R=1
S=1
,因此现在可以执行
Y
中的关键部分


问题:正确答案是(C),我哪里错了?

如果不是二进制信号量,“B”可以工作:在这种情况下,X可以创建一个元素,增加一个信号量,Y可以等待该信号量并使用这些项。信号量可以计算有多少项可供处理。一个信号灯就足够了

但是,您有二进制信号量。因此,您最多只能计数一个,例如,X可以创建一个元素,向信号量发送信号,但in不能继续创建元素,因为它不能将信号量值提高到“2”(或更多)。因此,它必须等待单个元素被Y识别,而这个等待引入了第二个信号量,在处理当前元素时发出X信号。需要记住的是,P会在必要时等待信号量增加(V会增加),因此X不能等待单个信号量返回0,因为没有这样的操作


这就是‘C’所做的,S实际上是‘数据就绪’信号,R是‘确认’。X说,它准备好了,然后等待确认。当Y等待就绪并发送确认时。

'B'如果不是二进制信号量就可以工作:在这种情况下,X可以创建一个元素,增加一个信号量,Y可以等待该信号量并使用这些项。信号量可以计算有多少项可供处理。一个信号灯就足够了

但是,您有二进制信号量。因此,您最多只能计数一个,例如,X可以创建一个元素,向信号量发送信号,但in不能继续创建元素,因为它不能将信号量值提高到“2”(或更多)。因此,它必须等待单个元素被Y识别,而这个等待引入了第二个信号量,在处理当前元素时发出X信号。需要记住的是,P会在必要时等待信号量增加(V会增加),因此X不能等待单个信号量返回0,因为没有这样的操作


这就是‘C’所做的,S实际上是‘数据就绪’信号,R是‘确认’。X说,它准备好了,然后等待确认。当y等待准备并发送确认时,

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

  • 在X循环完成之前,Y循环无法启动
    i
  • 在Y结束之前,X循环无法启动
    i+1
  • 因此有两个信号量,每个信号量管理上面的一点

    信号量达到1将需要从
    ExitX
    调用
    p
    。而
    EntryY
    需要调用
    V
    。B已经走了。要实现2,我们需要
    ExitX中的
    V
    EntryY中的
    P

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

    C做这项工作


    d不完全正确,因为无论是代码> x>代码>和<代码> y>代码>在调用该信号量的任何<代码> p < /代码>之前,两次都会碰到<代码> v>代码>。

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

  • 在X循环完成之前,Y循环无法启动
    i
  • 在Y结束之前,X循环无法启动
    i+1
  • 因此有两个信号量,每个信号量管理上面的一点

    信号量达到1将需要从
    ExitX
    调用
    p
    。而
    EntryY
    需要调用
    V
    。B已经走了。要实现2,我们需要
    ExitX中的
    V
    EntryY中的
    P

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

    C做这项工作


    D不太正确,因为在调用该信号量的任何
    p
    之前,
    X
    Y
    可能会击中
    V
    两次。

    B折叠两个锁,因此它不正确。这里的要点是协调两个循环。让我把它写下来。B折叠了两个锁,所以它不可能是正确的。这里的要点是协调两个循环。让我写下来。这里函数ExitX和EntryY被认为是原子的,对吗?@chunky不,不是。只有
    P
    V
    是原子的。在执行
    ExitX
    时,信号量的更新值是
    S=0,R=1
    ,因此现在根据
    选项(C)
    中的
    EntryY
    控制到达并执行,
    b[i]=g(a[i])
    过程Y
    中,现在更新的信号量值是
    S=1,R=0
    ,这确保了
    processx
    中的
    a[i]=f(i)
    再次运行,对吗?
    ExitX(R, S) {
        P(R);
        V(S);
    }
    
    EntryY (R, S) {
        P(S);
        V(R);
    }
    
    ExitX(R, S) {
        V(R);
        V(S);
    }
    
    EntryY(R, S) {
        P(R);
        P(S);
    }
    
    ExitX(R, S) {
        P(S);
        V(R);
    }
    
    EntryY(R, S) {
        V(S);
        P(R);
    }
    
    ExitX(R, S) {
        V(R);
        P(S);
    }
    EntryY(R, S) {
        V(S);
        P(R);
    }