Linux(服务器编程):42---Linux下常用错误码分析

一、EINTR

  • 当系统调用在阻塞期间接收到信号被中断,那么系统调用会出错返回-1,并将errno设置为EINTR
  • 当系统调用被中断之后,根据你的需求可以选择性的进行系统调用重启
  • 详情请参阅:https://blog.csdn.net/qq_41453285/article/details/89216990

二、EAGAIN、EWOULDBLOCK

  • 这两个错误码是相同的,被定义为同一个值
#define EAGAIN 11 /* Try again */

#define EWOULDBLOCK EAGAIN /* Operation would block */
  • 功能:一般用到非阻塞模式下返回的错误码 
  • 非阻塞模式可参阅:https://blog.csdn.net/qq_41453285/article/details/89856558
  • 具体什么含义就要看你调用的接口了,例如:
    • recv()、recvmsg()等接收数据的函数:在非阻塞模式下,没有数据可读,那么就返回-1并将errno设置为EAGAIN或EWOULDBLOCK
    • send()、sendmsg()等接收数据的函数:在非阻塞模式下,没有数据可发送,那么就返回-1并将errno设置为EAGAIN或EWOULDBLOCK
    • 对某些操作来说,资源短暂不可用。例如fork函数可能返回这个错误(当没有足够的资源能够创建一个进程时),可以采取的操作是休息一段时间然后再继续操作
  • 错误处理:
    • 最好的办法是重试,重试一定次数后还不成功就退出操作
    • 为什么不能无限重试呢?假设在通过socket发送一段数据,发送缓冲区如果一直不可写,就会出现无限循环的情况,进程卡死

情景分析①

  • 例如在epoll()中,当有一个套接字事件变为EPOLLIN时,程序调用recv()去读取数据,但是recv()返回-1,并且错误码为EAGAIN,说明没有数据可读
  • 为什么epoll_wait()检测到套接字事件变为EPOLLIN,但是recv()的时候数据又没有了呢?可能有多个线程调用recv()在同一个套接字上读取数据,在当前线程epoll_wait()返回与调用recv()之间,recv()的数据被另外一个线程的recv()读取完了,因此epoll_wait()检测到EPOLLIN,但是读取的时候数据却变为空
while(1)
{
    int rc = epoll_wait(xxx)
    if(rc > 0)
    {
        for(int i = 0; i < rc ; ++i)
        {
            rc = recv()
            if(rc < 0)
            {
                if(errono == EAGAIN || errno == EWOULDBLOCK)
                    continue;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/106911543