中断被阻止的读取

pkln4tw6  于 2022-10-23  发布在  Linux
关注(0)|答案(2)|浏览(177)

我的程序经历了一个循环,如下所示:

...
while(1){
  read(sockfd,buf,sizeof(buf));
  ...
}

Read函数在等待输入时阻塞,输入恰好来自套接字。我想要处理SIGINT,基本上是告诉它,如果它正在读取,就停止读取函数,然后调用任意函数。做这件事最好的方法是什么?

rbpvctlc

rbpvctlc1#

read(2)开始:

EINTR  The call was interrupted by a signal before any data
          was read; see signal(7).

如果您修改代码使其看起来更像:

cont = 1;
while (1 && cont) {
    ret = read(sockfd, buf, sizeof(buf));
    if (ret < 0 && errno == EINTR)
        cont = arbitrary_function();
}

这让arbitrary_function()决定是否应该重试read(2)

更新

您需要处理信号,以便从read(2)获得EINTR行为:


# include<unistd.h>

# include<stdio.h>

# include<stdlib.h>

# include<signal.h>

# include<errno.h>

int interrupted;

void handle_int(int num) {
  interrupted = 1;
}

int main(void){
  char buf[9001];
  struct sigaction int_handler = {.sa_handler=handle_int};
  sigaction(SIGINT,&int_handler,0);
  while(!interrupted){
    printf("interrupted: %d\n", interrupted);
    if(read(0,buf,sizeof(buf))<0){
      if(errno==EINTR){
        puts("eintr");
      }else{
        printf("%d\n",errno);
      }
      puts(".");
    }
  }
  puts("end");
  return 0;
}

给出输出:

$ ./foo
interrupted: 0
hello
interrupted: 0
^Ceintr
.
end
6l7fqoea

6l7fqoea2#

当您的进程收到信号时,read()将返回,errno的值将设置为EINTR

相关问题