现在的位置: 首页 > 综合 > 正文

linux下使用setitimer时accept返回Interrupted system call

2013年08月24日 ⁄ 综合 ⁄ 共 1116字 ⁄ 字号 评论关闭

    Android平台下程序中的一个线程使用setitimer,而主进程则作为套接字接收服务器,但是却经常出现 accept返回Interrupted system call错误,

追寻原因及解决方法:

 

 

 

出自unix网络编程(第三版)第五章 P115页。

 

我们用术语慢系统调用(slow system call)描述accept函数,该术语也适用于那些可能永远阻塞的系统调用。永远阻塞的系统调用有可能永远无法返回,多数网络支持函数都属于这一类。举例来说,如果没有客户连接到服务器上,那么服务器的accept调用就没有返回的保证,类似的如果客户端从未发送过数据,那么read调用将永不返回。其他慢系统调用的例子是对管道和终端设备的读和写。一个值得注意的例外是磁盘IO,它们一般都会返回到调用者(假设没有灾难性的硬件事故)。
  适用于慢系统调用的基本规则是:当阻塞于某个慢系统调用的一个进程捕获某个信号且相应处理函数返回时,该系统调用可能返回一个EINTR错误。所以,我们必须对慢系统调用返回的EINTR有所准备。
  为了处理被中断的accept,可以包装证:

 for (;;) {
    if ((connfd = accept(listenfd, NULL, NULL)) < 0) {
  if (errno == EINTR)
    continue;
  else
    err_sys("accept error");
    }  
        }
  这段代码所做的事情就是自己重启被中断的系统调用。对于accept以及诸如read、write、select和open之类的函数,这是适合的。不过有一个函数我们不能重启:connect。如果该函数返回EINTR,我们就不能再次调用它,否则将立即返回一个错误。当connect被一个捕获信号中断而且不自动重启时,我们必须调用select来等待连接完成。

http://www.cs.moravian.edu/pipermail/cs320/2008-February/000040.html

 

 

 

 

   在本人的程序中,为了能够使用一种机制,使accept不会被SIGALRM信号中断,尝试了使用pthread_sigmask函数,但pthread_sigmask 总是返回失败。无奈尝试了下再起一个线程,一个线程作为timer,另一个线程进行套接字数据接收处理,主线程通过等待互斥量来进行阻塞(不能使用sleep,Timer和sleep也会存在冲突,timer到时后的SIGALRM信号会导致sleep被唤醒),测试问题没有出现。。。

 

    多个线程的SIGALRM信号不会影响? 原因没有想明白,怀疑和Android内核处理有关。

 

 

 

抱歉!评论已关闭.