你所依赖的是一个比赛条件,一个你几乎永远不会赢的条件。
让我们来看看第一块:
do {
// Note the msg type: vvvvvvvvvv
msgrcv( id_i, &msg, dimensione, INCREMENTA, 0 );
// ...
// Note the msg type: vvvvvvv
msgrcv( id_i, &msg, dimensione, TERMINA, IPC_NOWAIT );
}
while( msg.tipo != TERMINA );
循环中的第二个“msgrcv”调用是您尝试查找终止符消息类型,然后返回顶部并阻塞,等待另一个
INCREMENTA
消息
考虑以下事件链:
Sender Receiver
--------------- -----------------
1 Call msgrcv with INCREMENTA. Block indefinitely
2 Send 'INCREMENTA'
3 msgrcv returns. Begin processing increment msg.
4 Processing finshed.
5 Call msgrcv with TERMINA.
6 No TERMINA message found (queue empty), returns immediately.
7 Go to top of loop.
8 Call msgrcv with INCREMENTA. Block indefinitely
9 Send 'TERMINA'
10 Nothing happens because we're waiting for 'INCREMENTA'.
您不能尝试以这种模式查询消息队列。如果事件8和9发生了逆转,你的逻辑可能会正常工作——但这是一个比赛条件,而且你很可能经常输掉比赛。
相反,为什么不使用
msgrcv
要接收任何类型的消息,然后在从队列中读取消息后,找出您收到的消息类型并从那里处理它。如果你通过
0
将“msgtyp”参数设置为
消息rcv
,它会给你所有的信息,然后你可以随心所欲地处理它。
while(true) {
// Get any msg type: vv
msgrcv( id_i, &msg, dimensione, 0, 0 );
if ( msg.tipo == TERMINA ) {
break;
}
else {
// ...
}
}