【问题标题】:Interrupting blocked read中断阻塞读取
【发布时间】:2011-06-06 08:47:36
【问题描述】:

我的程序会这样循环:

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

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

【问题讨论】:

    标签: c linux signals interrupt


    【解决方案1】:

    来自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(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
    

    【讨论】:

    • 根据您提供的内容,发送 SIGINT(通过 Ctrl+C)会结束程序。
    • @kaykun,仅当这是程序的最后一行时。您可以在 while 块之后添加更多行以重新启动传输,您可以删除该特定客户端并继续执行程序的主循环,您可以与用户启动一个交互式 shell,询问下一步要采取什么行动...没有什么说这必须终止程序。
    • @sarnold 不正确,至少对我而言,无论我在 while 循环后添加什么,发送 SIGINT 时程序都会终止,几乎所有其他命令行程序也是如此。跨度>
    • @kaykun,好吧,我假设你目前没有处理信号;已更新答案以显示如何忽略或处理 SIGINT
    • 使用 SIG_IGN 描述的 sigaction 只会使 Ctrl+C 什么都不做;读取静止块。您可以自己检查:pastebin.com/ybVt79tQ
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-03-08
      • 2016-07-27
      • 2014-11-17
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      相关资源
      最近更新 更多