我需要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/

10-10 02:30