我需要msgrcv的帮助...我需要能够接收如下消息:
while(1){
int status = msgrcv(qid, &msg, sizeof(msg.data), user_id,0 )
if(status < 0) { perror("something wrong..."); exit(1); }
}
还在代码的某处:
void stuff_to_do(int signal){
// ....
}
//...
signal(SIGQUIT, stuff_to_do);
但是我收到了系统中断消息,可能是因为信号杀死了msgrcv或类似的东西。
我该如何解决?我应该在一个进程中执行fork()并执行msgrcv,而在另一进程中执行该操作吗?或者,还有更好的方法?
谢谢您的帮助!
最佳答案
是的,如果您的进程在msgrcv()
期间收到信号,它将被中断。
从man pages on msgrcv()
:
调用过程捕获信号。在这种情况下,系统调用将errno设置为EINTR失败。 (msgrcv()永远不会在被信号处理程序中断后自动重新启动,而不管建立信号处理程序时是否设置SA_RESTART标志。)
尝试确定此故障情况,然后使用类似以下命令重新启动msgrcv()
while (1) {
// Try to receive message
errno = 0;
int status = msgrcv(qid, &msg, sizeof(msg.data), user_id,0 )
if (status < 0) {
if (errno == EINTR) continue; // try again
// Something else went wrong
perror("something wrong...");
exit(1);
}
}
不要忘记,您必须在要测试的操作之前手动设置
errno = 0
。这使我想起了描述并发性和同时性的good answer。它解释了为什么必须始终使用尝试该操作的方法,然后检查其是否成功。
也可以看看:
How to handle EINTR (interrupted System Call)
msgrcv - SA_RESTART flag doesn't work。
关于c - C-使msgrcv与信号共存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41071650/