gpt4 book ai didi

c - msgrcv - SA_RESTART 标志不起作用

转载 作者:太空狗 更新时间:2023-10-29 16:12:03 26 4
gpt4 key购买 nike

我使用 IPC 队列在线程之间进行通信的代码有问题。我需要安全地处理 SIGINT - 当 SIGINT 在关闭之前出现时让程序完成所有事件线程。虽然,我在寻找解决方案时遇到了严重的问题,因为即使使用带有标志 SA_RESTART 的 SIGINT 的 sigaction,msgrcv 函数也会出现 EINTR 错误。

我的问题是 - 除了 msgrcv 函数之外,还有什么方法可以避免 EINTR在一些“如果”中指定错误条件,例如:

if (msgrcv<0){
if (errno == EINTR){
errno = 0;
}
}

这是我用来演示问题的程序的真正简化版本:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/msg.h>

#define IPC_KEY 11000
#define BUF_SIZE 128

//structure of IPC message
typedef struct msgbuf{
long mtype;
char mtext[BUF_SIZE];
} message_buf;


void handle_sigint(int sig){
signal(SIGINT,SIG_IGN);
/*
some operation to handle sigint,
here it's really simple setting
SIGINT to be ignored
*/

}

int main(){

long ipc_id;
message_buf msg;
struct sigaction setup_action;
sigset_t block_mask;

//setup sigaction for SIGINT
sigemptyset(&block_mask);
sigaddset(&block_mask,SIGINT);
setup_action.sa_handler = handle_sigint;
setup_action.sa_mask = block_mask;
setup_action.sa_flags = SA_RESTART;
if (sigaction(SIGINT, &setup_action, 0) < 0){
perror("sigaction");
exit(1);
}

//creating the ipc queue
if ((ipc_id = msgget(IPC_KEY, IPC_CREAT | IPC_EXCL | 0666))<0){
perror("error in msgget");
exit(1);
}

for(;;){
if (msgrcv(ipc_id,&msg,BUF_SIZE,1,0)<0){
perror("error in msgrcv");
exit(1);
}
printf("received message : %s\n",msg.mtext);
}

}

这是清理 IPC 队列的简单程序:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/msg.h>

#define IPC_KEY 11000


int main(){

long ipc_id;

if ((ipc_id = msgget(IPC_KEY, IPC_CREAT | 0666 )) < 0) {
perror("error in msgget");
exit(1);
}

if (msgctl(ipc_id, IPC_RMID, 0) != 0){
perror("error in msgctl");
exit(1);
}


return 0;

}

在此先感谢您的帮助!我真的希望我没有提出重复的问题,但我试着寻找了一段时间的解决方案,不幸的是,除了使用 if 函数明确捕获 EINTR errno 之外,没有找到任何其他解决方案。

最佳答案

来自(Linux) manual :

The following interfaces are never restarted after being interrupted by a signal handler, regardless of the use of SA_RESTART; they always fail with the error EINTR when interrupted by a signal handler:

....

  • System V IPC interfaces: msgrcv(2), msgsnd(2), semop(2), and semtimedop(2).

SA_RESTART 的处理方式是位实现定义的。您没有使用特定的 Unix 风格进行标记,但我认为您的 Unix 根本不遵守特定系统调用的 SA_RESTART

关于c - msgrcv - SA_RESTART 标志不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27585075/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com