中断被阻止的读取

kay*_*kun 14 c linux signals interrupt

我的程序经历了这样的循环:

...
while(1){
  read(sockfd,buf,sizeof(buf));
  ...
}
Run Code Online (Sandbox Code Playgroud)

read函数在等待输入时阻塞,这恰好来自套接字.我想处理SIGINT并且基本上告诉它在读取时停止读取函数然后调用任意函数.做这个的最好方式是什么?

sar*_*old 16

来自read(2):

   EINTR  The call was interrupted by a signal before any data
          was read; see signal(7).
Run Code Online (Sandbox Code Playgroud)

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

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

这可以arbitrary_function()决定是否read(2)应该重新尝试.

更新

您需要处理信号以获取以下EINTR行为read(2):

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<errno.h>

int interrupted;

void handle_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;
}
Run Code Online (Sandbox Code Playgroud)

给出输出:

$ ./foo
interrupted: 0
hello
interrupted: 0
^Ceintr
.
end
Run Code Online (Sandbox Code Playgroud)

  • 如您在SIG_IGN中所述使用sigaction只会使Ctrl + C无效。读取静止块。您可以自己检查:http://pastebin.com/ybVt79tQ (2认同)