4.11 Linux EINTR 错误码

在类 Unix/Linux 操作系统中,当我们调用一些 socket 函数时(connect、send、recv、epoll_wait 等),除了函数调用出错会返回 -1,这些函数可能被信号中断也会返回 -1,此时我们可以通过错误码 errno 判断是不是 **EINTR ** 来确定是不是被信号中断。在实际编码的时候,请读者务必要考虑到这种情况。这也是上文中很多代码要专门判断错误码是不是 EINTR,如果是,说明被信号中断,我们需要再次调用这个函数进行重试。千万不要一看到返回值是 -1,草草认定这些调用失败,进而做出错误逻辑判断。

bool SendData(const char* buf , int buf_length)
{
 //已发送的字节数目
 int sent_bytes = 0;
 int ret = 0;
 while (true)
 {
     ret = send(m_hSocket, buf + sent_bytes, buf_length - sent_bytes, 0);
     if (nRet == -1)
     {
         if (errno == EWOULDBLOCK)
         {
             //严谨的做法,这里如果发不出去,应该缓存尚未发出去的数据,后面介绍
             break;
         }             
         else if (errno == EINTR)
             continue;
         else
             return false;
     }
     else if (nRet == 0)
     {
         return false;
     }

     sent_bytes += ret;
     if (sent_bytes == buf_length)
         break;
 
     //稍稍降低 CPU 的使用率
     usleep(1);
 }
 
 return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

本节完。

上次更新: 2025/04/01, 20:53:14

社区交流

讨论与留言

前往 GitHub Issues →

本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。

最近更新
第 1 课:专栏导论与安全边界
07-01
第 3 课:安装编译与调试环境
07-01
第 4 课:第三方库下载、编译与依赖管理
07-01
更多文章>