C 如何使用信号量实现屏障
我有以下问题需要解决: 考虑一个应用程序,其中有三种类型的线程:演算-A、演算-B和终结。每当线程类型演算-a结束时,它调用例程endA(),该例程立即返回。每当线程类型演算-B结束时,它调用例程endB(),该例程立即返回。终止例程调用wait()之类的线程, 仅当它们已完成两个计算-A线程和两个计算-B线程时返回。换句话说,对于演算-A的2个结论和演算-B的2个结论,允许继续执行一个线程终结。 这3种类型的线程数量尚未确定。线程调用的例程的顺序未知。线程完成按到达顺序应答。 使用信号量实现例程endA()、endB()和wait()。除了变量初始化,唯一可能的操作是P和V。不接受等待繁忙的解决方案 以下是我的解决方案:C 如何使用信号量实现屏障,c,multithreading,semaphore,C,Multithreading,Semaphore,我有以下问题需要解决: 考虑一个应用程序,其中有三种类型的线程:演算-A、演算-B和终结。每当线程类型演算-a结束时,它调用例程endA(),该例程立即返回。每当线程类型演算-B结束时,它调用例程endB(),该例程立即返回。终止例程调用wait()之类的线程, 仅当它们已完成两个计算-A线程和两个计算-B线程时返回。换句话说,对于演算-A的2个结论和演算-B的2个结论,允许继续执行一个线程终结。 这3种类型的线程数量尚未确定。线程调用的例程的顺序未知。线程完成按到达顺序应答。 使用信号量实现例
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。我说可能是因为我不确定“按照到达的顺序回答”是什么意思
V
和p
,我将使用take()
/give()
groupSem
信号量确保要么全有,要么全无:进入临界段的线程将获得下两个完成的CalcA和CalcB。如果groupSem
不在那里,那么进入wait
的第一个线程可能会占用两个As和block,然后被另一个线程接管,该线程会占用两个As和两个B,然后跑掉
如果没有
groupSem
则存在一个更糟糕的问题,即第二个线程使用两个As,一个B,然后阻塞,然后第一个线程抓住第二个B。如果最终确定的结果允许更多的CalculationA和CalculationB运行,则可能会出现死锁,因为可能没有更多的机会让计算A和B的实例完成,因此使终结线程挂起,无法生成更多的计算实例。我倾向于将信号量问题视为必须识别“等待源”的问题并为每个用户定义一个信号量和访问协议
考虑到这一点,“等待的来源”是
- 钙的完成
- 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);
}