我的作业是以钻石图案对一系列信号量进行等待和发出信号。
以下是模式:
08
06 07
03 04 05
01 02
00
Thread #08 cannot join the diamond until threads #06 and #07 are both in position.
Thread #07 cannot join until threads #04 and #05 are both in position.
Thread #06 cannot join until threads #03 and #04 are both in position. and so on...
到目前为止,我的想法导致了以下丑陋的算法:
if (me==0) {
wait_sem (tCount[1]) ;
wait_sem (tCount[2]) ;
signal_sem (tCount[0]) ;
}
if (me==1) {
wait_sem (tCount[3]) ;
wait_sem (tCount[4]) ;
}
if (me==2) {
wait_sem (tCount[4]) ;
wait_sem (tCount[5]) ;
}
if (me==3) {
wait_sem (tCount[6]) ;
}
if (me==4) {
wait_sem (tCount[6]) ;
wait_sem (tCount[7]) ;
}
if (me==5) {
wait_sem (tCount[7]) ;
}
if (me==6) {
wait_sem (tCount[8]) ;
}
if (me==7) {
wait_sem (tCount[8]) ;
}
有更干净的方法吗?我听说switch
但我以前从未使用它,所以如果有人建议,请给我一个解释和示例。非常感谢所有的投入。
答案 0 :(得分:3)
让我们采用一种非常简单的方法,将信号量保存在全局数组中(或者只是可以访问线程)。您可以设置依赖项列表,如下所示:
std::vector<std::vector<int>> thread_depends = {
{ }, // 0
{ 0 }, // 1
{ 0 }, // 2
{ 1 }, // 3
{ 1, 2 }, // 4
{ 2 }, // 5
{ 3, 4 }, // 6
{ 4, 5 }, // 7
{ 6, 7 }, // 8
};
现在,每个线程都需要等待thread_depends[me]
中的所有内容:
const auto & dep = thread_depends[me];
std::for_each( dep.begin(), dep.end(), [&tCount](int who){ wait_sem( tCount[who] ); } );
signal_sem( tCount[me] );
这种方法的好处是你不会复制每个案例的操作逻辑。相反,您只是代表依赖项,而您只有一段代码可以完成实际工作。这意味着制作复制粘贴错误的可能性更小。
答案 1 :(得分:1)
这个解决方案只是为了展示如何用case完成,有更好的实现这个问题!
切换比if / else更好,因为它可以作为跳转,如果需要测试所有条件直到满足(if0,if1,if2 ......),交换机将直接到正确的案例。
switch(me)
{
case 0:
wait_sem(tCount[1]);
wait_sem(tCount[2]);
signal_sem(tCount[me]);
break;
case 1:
wait_sem(tCount[3]) ;
wait_sem(tCount[4]) ;
signal_sem(tCount[me]);
break;
case 2:
wait_sem(tCount[4]);
wait_sem(tCount[5]);
signal_sem(tCount[me]);
break;
case 3:
wait_sem(tCount[6]);
signal_sem(tCount[me]);
break;
case 4:
wait_sem(tCount[6]);
wait_sem(tCount[7]);
signal_sem(tCount[me]);
break;
case 5:
wait_sem(tCount[7]);
signal_sem(tCount[me]);
break;
case 6:
wait_sem(tCount[8]);
signal_sem(tCount[me]);
break;
case 7:
wait_sem(tCount[8]);
signal_sem(tCount[me]);
break;
case 8:
signal_sem(tCount[me]);
break;
}