C - 使 msgrcv 与信号共存
C - make msgrcv coexist with signals
我需要一些有关 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()
期间收到信号,它将被中断。
The calling process catches a signal. In this case the system call fails with errno set to EINTR. (msgrcv() is never automatically restarted after being interrupted by a signal handler, regardless of the setting of the SA_RESTART flag when establishing a signal handler.)
尝试识别这种故障情况,然后用
之类的东西重新启动 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.
我需要一些有关 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()
期间收到信号,它将被中断。
The calling process catches a signal. In this case the system call fails with errno set to EINTR. (msgrcv() is never automatically restarted after being interrupted by a signal handler, regardless of the setting of the SA_RESTART flag when establishing a signal handler.)
尝试识别这种故障情况,然后用
之类的东西重新启动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.