Interrupting blocked read

主宰稳场 提交于 2019-12-03 11:45:14

问题


My program goes through a loop like this:

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

The read function blocks when it is waiting for input, which happens to be from a socket. I want to handle SIGINT and basically tell it to stop the read function if it is reading and then call an arbitrary function. What is the best way to do this?


回答1:


From read(2):

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

If you amend your code to look more like:

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

This lets arbitrary_function() decide if the read(2) should be re-tried or not.

Update

You need to handle the signal in order to get the EINTR behavior from 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;
}

Gives output:

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



回答2:


When your process receives a signal, read() will return and the value of errno will be set to EINTR.



来源:https://stackoverflow.com/questions/6249577/interrupting-blocked-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!