Socket编程中Interrupted system call 解释及解决办法

本文深入探讨了在处理慢系统调用时遇到的信号中断问题,特别是针对接受函数(accept)的实现,强调了在使用时如何正确处理EINTR错误,以确保程序的稳定性和鲁棒性。通过示例代码,展示了如何重新启动被中断的系统调用,以避免因信号中断导致的程序失败。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载出处: http://blog.chinaunix.net/uid-25885064-id-3071372.html


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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值