Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用信号量实现屏障_C_Multithreading_Semaphore - Fatal编程技术网

C 如何使用信号量实现屏障

C 如何使用信号量实现屏障,c,multithreading,semaphore,C,Multithreading,Semaphore,我有以下问题需要解决: 考虑一个应用程序,其中有三种类型的线程:演算-A、演算-B和终结。每当线程类型演算-a结束时,它调用例程endA(),该例程立即返回。每当线程类型演算-B结束时,它调用例程endB(),该例程立即返回。终止例程调用wait()之类的线程, 仅当它们已完成两个计算-A线程和两个计算-B线程时返回。换句话说,对于演算-A的2个结论和演算-B的2个结论,允许继续执行一个线程终结。 这3种类型的线程数量尚未确定。线程调用的例程的顺序未知。线程完成按到达顺序应答。 使用信号量实现例

我有以下问题需要解决:

考虑一个应用程序,其中有三种类型的线程:演算-A、演算-B和终结。每当线程类型演算-a结束时,它调用例程endA(),该例程立即返回。每当线程类型演算-B结束时,它调用例程endB(),该例程立即返回。终止例程调用wait()之类的线程, 仅当它们已完成两个计算-A线程和两个计算-B线程时返回。换句话说,对于演算-A的2个结论和演算-B的2个结论,允许继续执行一个线程终结。 这3种类型的线程数量尚未确定。线程调用的例程的顺序未知。线程完成按到达顺序应答。 使用信号量实现例程endA()、endB()和wait()。除了变量初始化,唯一可能的操作是P和V。不接受等待繁忙的解决方案

以下是我的解决方案:

semaphore calcA = 2;
semaphore calcB = 2;
semaphore wait = -3;

void endA()
    {
        P(calcA);
        V(wait);
    }

void endB()
    {
        P(calcB);
        V(wait);
    }

void wait()
    {
        P(wait);
        P(wait);
        P(wait);
        P(wait);
        V(calcA);
        V(calcA);
        V(calcB);
        V(calcB);
    }

我相信由于wait的初始化以及if和wait()在endA()和endB()之前执行,会出现死锁。还有其他解决方案吗?

我倾向于将信号量问题视为必须识别“等待源”并为每个源定义信号量和访问协议的问题

考虑到这一点,“等待的来源”是

  • 钙的完成
  • CalcB的完备性
  • 如果我理解正确的话,可能需要等待整个完成小组,包括两个CALCA和两个CALCB。我说可能是因为我不确定“按照到达的顺序回答”是什么意思
因此,CalcA和CalcB的完成应增加其各自的计数器。在另一端,一个终结线程获得对计数器的独占访问权,并以任意顺序等待所需数量的完成以组成完成组。然后,它将解锁对下一个组的访问

下面是我的代码,不过由于我不熟悉荷兰语
V
p
,我将使用
take()
/
give()

groupSem
信号量确保要么全有,要么全无:进入临界段的线程将获得下两个完成的CalcA和CalcB。如果
groupSem
不在那里,那么进入
wait
的第一个线程可能会占用两个As和block,然后被另一个线程接管,该线程会占用两个As和两个B,然后跑掉


如果没有
groupSem
则存在一个更糟糕的问题,即第二个线程使用两个As,一个B,然后阻塞,然后第一个线程抓住第二个B。如果最终确定的结果允许更多的CalculationA和CalculationB运行,则可能会出现死锁,因为可能没有更多的机会让计算A和B的实例完成,因此使终结线程挂起,无法生成更多的计算实例。

我倾向于将信号量问题视为必须识别“等待源”的问题并为每个用户定义一个信号量和访问协议

考虑到这一点,“等待的来源”是

  • 钙的完成
  • CalcB的完备性
  • 如果我理解正确的话,可能需要等待整个完成小组,包括两个CALCA和两个CALCB。我说可能是因为我不确定“按照到达的顺序回答”是什么意思
因此,CalcA和CalcB的完成应增加其各自的计数器。在另一端,一个终结线程获得对计数器的独占访问权,并以任意顺序等待所需数量的完成以组成完成组。然后,它将解锁对下一个组的访问

下面是我的代码,不过由于我不熟悉荷兰语
V
p
,我将使用
take()
/
give()

groupSem
信号量确保要么全有,要么全无:进入临界段的线程将获得下两个完成的CalcA和CalcB。如果
groupSem
不在那里,那么进入
wait
的第一个线程可能会占用两个As和block,然后被另一个线程接管,该线程会占用两个As和两个B,然后跑掉


如果没有
groupSem
则存在一个更糟糕的问题,即第二个线程使用两个As,一个B,然后阻塞,然后第一个线程抓住第二个B。如果最终确定的结果允许更多的CalculationA和CalculationB运行,则可能会出现死锁,因为可能没有更多的机会让计算A和B的实例完成,因此使终结线程挂起,无法生成更多的计算实例。

为什么需要信号量
等待
?(请记住endA和endB必须立即返回)我创建了
信号量wait
,以确保进程
wait()
仅在执行2个线程calculation-A和2个线程calculation-B之后才执行。您是否认为信号量
wait
以及与之相关的所有指令都可能被忽略?为什么需要信号量
wait
?(请记住endA和endB必须立即返回)我创建了
信号量wait
,以确保进程
wait()
仅在执行2个线程calculation-A和2个线程calculation-B之后才执行。您是否认为信号量
wait
以及与之相关的所有指令都可能被忽略?
semaphore calcA    = 0;
semaphore calcB    = 0;
semaphore groupSem = 1;

void endA(){
    give(calcA);
}

void endB(){
    give(calcB);
}

void wait(){
    take(groupSem);
    take(calcA);
    take(calcA);
    take(calcB);
    take(calcB);
    give(groupSem);
}