C 为什么阻塞接收工作和非阻塞don';T

C 为什么阻塞接收工作和非阻塞don';T,c,unix,ipc,message,message-queue,C,Unix,Ipc,Message,Message Queue,我在写阻塞和非阻塞接收的例子 我使用带有IPC_NOWAIT标志的msgrcv作为非阻塞接收 和带有0标志的msgrcv作为阻塞接收 然后我从另一个进程发送了一些消息 如果我尝试只使用阻塞接收,则它们会正确地接收消息 我还尝试将非阻塞接收放在一个while循环中(它们应该一直工作,直到终止消息到达)。但许多非阻塞接收不起作用。似乎只有等待终止消息的非阻塞接收才能工作 显然,我只发布非工作代码 接收程序: while(terminato == 0) {msgrcv(id_interfaccia,&

我在写阻塞和非阻塞接收的例子

我使用带有IPC_NOWAIT标志的msgrcv作为非阻塞接收

和带有0标志的msgrcv作为阻塞接收

然后我从另一个进程发送了一些消息

如果我尝试只使用阻塞接收,则它们会正确地接收消息

我还尝试将非阻塞接收放在一个while循环中(它们应该一直工作,直到终止消息到达)。但许多非阻塞接收不起作用。似乎只有等待终止消息的非阻塞接收才能工作

显然,我只发布非工作代码

接收程序:

while(terminato == 0)
{msgrcv(id_interfaccia,&msg,dim,NOTIFICA_AVVIO_CONTROLLORE,IPC_NOWAIT);
if(errno==0)
{printf("Controllore avviato\n");
}
msgrcv(id_interfaccia,&msg,dim,NOTIFICA_AVVIO_MIXER,IPC_NOWAIT);
if(errno==0)
{printf("Mixer avviato\n");
}


msgrcv(id_interfaccia,&msg,dim,NOTIFICA_INTERRUZIONE_MIXER,IPC_NOWAIT);
if(errno==0)
{   printf("Il controllore ha inviato il messaggio di interruzione al mixer\n");
}
msgrcv(id_interfaccia,&msg,dim,NOTIFICA_INTERRUZIONE_TERMOSTATO,IPC_NOWAIT);
{printf("Il controllore ha inviato il messaggio di interruzione al termostato\n");
}
    msgrcv(id_interfaccia,&msg,dim,NOTIFICA_AVVIO_TERMOSTATO,IPC_NOWAIT);
{printf("Il controllore ha inviato il messaggio di avvio al termostato\n");
}

msgrcv(id_interfaccia,&msg,dim,NOTIFICA_TERMINAZIONE_MIXER,IPC_NOWAIT);
if(errno==0)
{   printf("Il controllore ha inviato il messaggio di terminazione al mixer\n");
}
    msgrcv(id_interfaccia,&msg,dim,NOTIFICA_TERMINAZIONE_TERMOSTATO,IPC_NOWAIT);
if(errno==0)
{   printf("Il controllore ha inviato il messaggio di terminazione al termostato\n");
}

msgrcv(id_interfaccia,&msg,dim,TEMP,IPC_NOWAIT);
if(errno==0)
{printf("INTERFACCIA Aggiornamento temperatura:%d\n",msg.contenuto);
}
msgrcv(id_interfaccia,&msg,dim,TERMINA,IPC_NOWAIT);
if(errno==0);
{printf("INTERFACCIA Messaggio di terminazione\n");     
terminato = 1;
}
}
发送程序

 invia(id_interfaccia,NOTIFICA_AVVIO_CONTROLLORE,&msg);
  invia(id_mixer,AVVIA,&msg);
 invia(id_interfaccia,NOTIFICA_AVVIO_MIXER,&msg);
 sleep(3);
 invia(id_mixer,INTERROMPI,&msg);
 invia(id_interfaccia,NOTIFICA_INTERRUZIONE_MIXER,&msg);
 invia(id_termostato,AVVIA,&msg);
 printf("Il controllore ha inviato il messaggio di avviamento al           termostato\n");

 while(check<50)
{
msgrcv(id_controllore,&msg,dim,TEMP,0);
check = msg.contenuto;
msg.tipo = TEMP;
msg.contenuto = check;
msgsnd(id_interfaccia,&msg,dim,0);
}
 invia(id_termostato,INTERROMPI,&msg);
 invia(id_interfaccia,NOTIFICA_INTERRUZIONE_TERMOSTATO,&msg);
 invia(id_mixer,TERMINA,&msg);
 invia(id_interfaccia,NOTIFICA_TERMINAZIONE_MIXER,&msg);
  invia(id_termostato,TERMINA,&msg);

类型结构消息有类型(tipo)和内容(ContentNuto)字段。

请显示两种情况的代码,显示您不理解的程序输出,并说明您期望的输出。完成。问题是只有一个/两个printfs工作请注意,errno仅保证在msg*返回-1时设置。您必须首先检查返回值。类似(msgrcv()>0)这样的检查是否有效?是的,我个人会使用类似
st=msgrcv();if(st<0){//Error handling}
以获得更好的可读性
void invia(int dest,int tipo,messaggio* pointer)
{pointer->tipo = tipo;
msgsnd(dest,pointer,dim,0);
}
void ricevi (int dest,int tipo,messaggio* pointer)
{msgrcv(dest,pointer,dim,tipo,0);
}