首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

处于阻塞模式的管道上的select()返回EAGAIN

处于阻塞模式的管道上的select()返回EAGAIN是指在使用select()函数进行I/O多路复用时,当管道处于阻塞模式且没有数据可读时,select()函数会返回EAGAIN错误码。

管道是一种用于进程间通信的机制,它可以在一个进程中写入数据,然后在另一个进程中读取这些数据。在阻塞模式下,当管道中没有数据可读时,读取操作会被阻塞,直到有数据可读为止。

select()函数是一种I/O多路复用的机制,它可以同时监视多个文件描述符的可读、可写和异常事件。当某个文件描述符上有可读事件时,select()函数会返回该文件描述符,从而实现非阻塞的I/O操作。

当处于阻塞模式的管道上调用select()函数时,如果管道中没有数据可读,select()函数会阻塞等待,直到有数据可读或者其他事件发生。但是如果管道处于阻塞模式且没有数据可读,select()函数会返回EAGAIN错误码,表示当前没有可读事件。

在这种情况下,可以通过以下方式解决问题:

  1. 使用非阻塞模式:将管道设置为非阻塞模式,这样在没有数据可读时,读取操作会立即返回,不会阻塞等待。
  2. 使用其他I/O多路复用机制:如epoll、kqueue等,这些机制相比select()函数更加高效,可以更好地处理大量的文件描述符。
  3. 使用其他同步机制:如条件变量、信号量等,可以通过这些机制实现线程间的同步和通信。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

5.epoll水平触发和边缘触发

LT处理过程中,直到返回EAGAIN不是硬性要求,但通常处理过程都会读写直到返回EAGAIN, 但LT比ET多了一个开关EPOLLOUT事件步骤。...LT编程与poll/select接近,符合一直以来习惯,不易出错。...二 、内核调度实现方式 在epoll_wait时候,阻塞等待事件发生, 事件发生时通过回调挂到ready list链表中 epoll_wait返回, 处理ready list, 返回事件给调用者 此时...ET模式继续阻塞 LT模式由于ready list中依然存在事件则不会阻塞, 对这些socket调用poll方法获取最新事件信息,如果确认没事件了才会删除。 ?...由于线程 A 还没有处理完(没有返回 EAGAIN), 当前 socket 还处于可读状态,由于是边缘触发模式,所有不会产生新事件 5.线程A:继续执行 accept() 希望返回 EAGAIN 再进入

4.6K62

Linux下C编程(3)

这个在GLIBC中设计了两个新函数就是SELECT/POLL。以下是几种I/O模型比较图: 1)阻塞I/O模型,缺省套接口都是阻塞,你使用READ时一定要有数据时进程才会进行下去。...2)非阻塞I/O,在将套接口设置为非阻塞方式下,内核就让请求I/O操作在没有数据情况直接返回一个错误,不再等特。显然这种操作需要不停尝试,消耗非常多CPU。 ?...另外一个相对于poll需要对保存FD集合数据结构进行线性扫描,并返回对应事件这种模式改进,FD不再进行线性扫描,它只针对活跃SOCKET进行操作,具体实现就是内核会对FD进行回调实现,只有活跃SOCKET...Epoll对事件触发方式提供了两种选择,一种是默认LT模式,即Level trigger,适应于非阻塞阻塞I/O,缺省。这种模式下内核会一直触发,直到事件被用户消费掉。...而ET模式,俗称Edge trigger,边沿触发适用于非阻塞模式下,在这种模式下,当文件描述符从未就绪变为就绪时,内核通过epoll告诉你,然后内核假设你已知道文件描述符已就绪,可以进行读写。

5.2K20
  • 关于IO模型,和select、poll、epoll区别

    所谓阻塞方式意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止;而对于非阻塞状态,如果没有东西可读,或者不可写,读写函数马上返回...,而不会等待,O_NONBLOCK 标志打开文件/Socket/FIFO句柄,如果连续做 read 操作而没有数据可读,此时程序不会阻塞起来等待数据准备就绪返回,read 函数会返回一个错误 EAGAIN...和 select 函数一样,poll 返回后,需要轮询 pollfd 来获取就绪描述符。 select 和 poll 都需要在返回后,通过遍历文件描述符来获取已经就绪 socket。...事实上,同时连接大量客户端在某一时刻可能只有很少处于就绪状态,因此随着监视描述符数量增长,效率也会线性下降。...epollET模式下,正确读写方式是: 读: 只要可读, 就一直读,直到返回0,或者 errno = EAGAIN 写:只要可写, 就一直写,直到数据发送完,或者 errno = EAGAIN 思考

    37720

    从Go编程看IO多路复用Select

    IO多路复用通过某种机制使进程监听某些文件描述符,当文件描述符中有读或写就绪时,进程能够收到系统内核发送相应通知从而进行相应IO操作;IO多路复用有:select、poll、epoll等模式,这里主要介绍...selectselect本质上也是同步IO,调用时阻塞自己,IO事件就绪后被唤醒返回负责读写操作; 在Go中其函数定义如下: func Select(nfd int, r *FdSet, w *FdSet...;   tcp连接中可只需关注是否可读即可; 函数返回:   通过函数返回可知这么两类信息:   1、准备好文件描述符个数   2、具体哪些文件描述符处于就绪可读、可写或异常状态 函数值:   ...= nil { log.Println(err) //非阻塞模型下资源限制或不满足条件返回eagain 异常Resource temporarily unavailable...) { //接受连接 nfd, naddr, err := syscall.Accept(fd) //阻塞模式下在此方法会阻塞 if err !

    72750

    一举拿下网络 IO 模型

    所谓阻塞型接口是指系统调用时却不返回调用结果,并让当前线程一直处于阻塞状态,只有当该系统调用获得结果或者超时出错时才返回结果。 实际上,除非特别指定,几乎所有的 IO 接口都阻塞。...这给网络编程带来了一个很大问题,如在调用 send 同时,线程处于阻塞状态,则在此期间,线程将无法执行任何运算或响应任何网络请求。...recv 返回 -1 ,且 errno 等于 EAGAIN ,表示 recv 操作还没执行完成。...此外,在这个方案 recv 更多是起到检测“操作是否完成”作用,实际操作系统提供了更为高效检测“操作是否完成”作用接口,例如 select 多路复用模式,可以次检测多个连接是存活跃。...当用户进程调用了 select ,那么整个进程会被阻塞,而同时,内核会 "监视" 所有 select 负责 socket ,当任何一个 socket 中数据准备好了, select 就会返回

    71220

    linux网络编程系列(十)--epoll基本使用

    网络编程中四种IO模型 阻塞IO模型,默认socket都是阻塞,就是IO操作都要等待操作完成以后才能返回; 非阻塞IO模型,就是IO操作时不等待,立即返回,但需要不断去询问内核,数据是否准备好了,...如果准备好了,就主动调用函数去处理数据,使用fcntl设置socket为非阻塞; 多路复用模型,就是事件驱动IO,也就是说检测到描述符上发生了事件,才去处理,典型就是select和epoll; 异步IO...2.1.1 LT模式(又叫水平模式,类似于select/poll): 完全靠内核驱动,只要某个文件描述符有变化,就会一直通知我们应用程序,直到处理完毕为止。...这时应用程序需要自己维护一张fds表格,把从epoll_wait得到状态信息登记到这张表格,然后应用程序可以选择遍历这张表格,对处于忙碌状态fds进行操作。...而且由于epollwait每次返回fds数量是有限,在大并发模式下,LT将非常繁忙,所有的fds都要在它队列中产生状态信息,而每次只有一部分fds能返回给应用程序。

    1.1K30

    linux网络编程系列(九)--epoll基本使用

    网络编程中四种IO模型 阻塞IO模型,默认socket都是阻塞,就是IO操作都要等待操作完成以后才能返回; 非阻塞IO模型,就是IO操作时不等待,立即返回,但需要不断去询问内核,数据是否准备好了,...如果准备好了,就主动调用函数去处理数据,使用fcntl设置socket为非阻塞; 多路复用模型,就是事件驱动IO,也就是说检测到描述符上发生了事件,才去处理,典型就是select和epoll; 异步IO...2.1.1 LT模式(又叫水平模式,类似于select/poll): 完全靠内核驱动,只要某个文件描述符有变化,就会一直通知我们应用程序,直到处理完毕为止。...这时应用程序需要自己维护一张fds表格,把从epoll_wait得到状态信息登记到这张表格,然后应用程序可以选择遍历这张表格,对处于忙碌状态fds进行操作。...而且由于epollwait每次返回fds数量是有限,在大并发模式下,LT将非常繁忙,所有的fds都要在它队列中产生状态信息,而每次只有一部分fds能返回给应用程序。

    77020

    对基于 TCP 网络应用在 socket 非阻塞模式下 send 调用错误原因深入分析

    socket可以被设置为阻塞和非阻塞两种属性;默认被设置为阻塞属性,调用send时,若发送缓冲区中空闲空间长度比请求发送数据更长,则函数直接返回;否则,则会确保所有数据被拷贝到内核之后再返回。...若socket被设置非阻塞属性,若缓冲区空间不足,则竟可能多拷贝数据,send函数返回实际拷贝字节数目,若空闲空间为0,则返回-1,并将errno设为EAGAIN。...,再次调用send发送数据时,若socket为阻塞,send会一直阻塞到发送缓冲区中有空闲空间;若socket为非阻塞,则会直接返回-1,并将errno设置为EAGAIN。...为了不让此类情况发生,应当避免在对非阻塞socket调用send失败之后立即关闭socket;一般采用下列几种方法来处理数据发送: 1) 当socket为非阻塞模式下时,send返回-1且errno...2) 当socket为阻塞模式下时,为socket设置O_SNDTIMEO超时参数,当send函数未在设置时间内完成任务,则函数返回错误,这时可以采用和1)中相同重试策略。

    2.5K02

    linux系统中socket错误码:EINTR和EAGAIN处理

    该术语适用于那些可能永远阻塞系统调用。永远阻塞系统调用是指调用永远无法返回,多数网络支持函数都属于这一类。如:若没有客户连接到服务器上,那么服务器accept调用就会永远阻塞。...-(一般用于非阻塞系统调用) 非阻塞系统调用,由于资源限制/不满足条件,导致返回值为EAGAIN 在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见一个错误...此时程序不会阻塞起来等待数据准备就绪返回,read函数会返回一个错误EAGAIN,提示你应用程序现在没有数据可读请稍后再试。...⇒ ⇒ ⇒ 这表明在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket同步,不用管它,下次循环接着recv就可以。...对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN名字叫做EWOULDBLOCK。

    5.9K10

    关于 liunx selectrecv函数返回值理解

    先从read函数 返回实际读取到字节数 ,属于io基本操作说起 关于 ②返回值等于0讨论 非阻塞 返回值等零表示没有数据可读 (这个理解是错误 如果没有数据返回应该是EAGAIN阻塞情况下:...select/epoll检测可读情况下,read返回0表示远端close 异常断开 总结: 阻塞接收recv有时候会返回0,这仅在socket被正常关闭时才会发生。...此时程序不会阻塞起来等待数据准备就绪返 回, read函数会返回一个错误EAGAIN, 提示你应用程序现在没有数据可读请稍后再试。...重新读数据, 在linux进行非阻塞socket接收数据时经常出现Resource temporarily unavailable, errno代码为11(EAGAIN) EINTER:系统在接收时候因为收到其他中断信号而被迫返回...频繁返回呀, 回答:是 ,select 如果检测多个不适合业务比较频繁 我们目前只监控1个 2 read函数缺点 回答 网络异常仍然阻塞住,需要借助keepavlie机制 3 事件触发机制 是如何触发

    3.2K50

    epoll使用详解

    (毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。...epoll工作在ET模式时候,必须使用非阻塞套接口,以避免由于一个文件句柄阻塞读/阻塞写操作把处理多个文件描述符任务饿死。...i    基于非阻塞文件句柄    ii   只有当read(2)或者write(2)返回EAGAIN时才需要挂起,等待。...如果你不作任何操作,内核还是会继续通知你,所以,这种模式编程出错误可能性要小一点。传统select/poll都是这种模型代表....在socket_send()内部,当写缓冲已满(send()返回-1,且errno为EAGAIN),那么会等待后再重试.这种方式并不很完美,在理论上可能会长时间阻塞在socket_send()内部,但暂没有更好办法

    3.6K10

    tcp粘包问题补充

    上篇文章 提到阻塞(block)一下如何read数据 这里针对是非阻塞如何read数据 并且纠正前面出现几个错误 (1) 非阻塞 遇到errno=EAGAIN必须continue处理 ,epoll_wait...3 缓冲区有数据但是属于上次遗留 不触发 参考 man epoll 例子 如果是ET模式,管道中剩余1KB被挂起,再次调用epoll_wait,得不到管道读者文件句柄,除 非有新数据写入管道...//所以,在epollET模式下,正确读写方式为: 读:只要可读,就一直读,直到返回0,或者 errno = EAGAIN(break 满足下次触发条件) 写:只要可写,就一直写,直到数据发送完...,或者 errno = EAGAIN(break 满足下次触发条件) 在epollLT模式下相反 读:忽略掉errno = EAGAIN错误,下次继续读 continue 写:忽略掉...errno = EAGAIN错误,下次继续写 ?

    1.1K60

    网络IO模型

    如在本例中, recv() 返回值大于 0,表示接受数据完毕,返回值即是接受到字节数; recv() 返回 0,表示连接已经正常断开; recv() 返回 -1,且 errno 等于 EAGAIN...,表示 recv 操作还没执行完成; recv() 返回 -1,且 errno 不等于 EAGAIN,表示 recv 操作遇到系统错误 errno。...但是轮询调用recv()也会带来CPU消耗。系统有更高效接口来判断是否操作完成方法。例如:select 多路复用模式,可以一次检测多个连接是否活跃。...多路复用模式IO 多路复用模式IO其实就是常说select/epoll,这种IO方式称之为事件驱动。这种模式好处就是在于单个进程可以同时处理多个网络连接IO....image.png 图中是信号IO处理模型,这种模型优势在于第一时间收到数据准备好消息,免去了select阻塞和轮询。

    82120

    ACCEPT()和ACCEPT4()

    它取出在监听套接口 sockfd请求队列里第一个连接,新建一个已连接套接口,并且返回一个引用该套接口新文件描述符。新建套接口不处于监听状态。原始套接口 sockfd 没有受到影响。...如果没有未处理连接,同时套接口被标记为不阻塞,accept() 返回EAGAIN 或 EWOULDBLOCK 错误。...可靠应用应该在调用 accept() 之后检测相应协议可能网络错误,并且处理 EAGAIN 一样重试一次。...错误 EAGAIN 或 EWOULDBLOCK 套接口被标记为非阻塞并且没有连接等待接受。...在 SIGIO 递送之后,在 select(2) 或 poll(2) 返回但连接却因为一个异步网络错误而删除之后,或在其它线程调用accept() 之前,不需要总是等待。

    1.8K20

    L011Linux和androidNDK之socket出错情况处理:Interrupted system call,Try again

    永远阻塞系统调用有可能永远无法返回,多数网络支持函数都属于这一类。举例来说,如果没有客户连接到服务器上,那么服务器accept调用就没有返回保证。...适用于慢系统调用基本规则是:当阻塞于某个慢系统调用一个进程捕获某个信号且相应处理函数返回时,该系统调用可能返回一个EINTR错误。所以,我们必须对慢系统调用返回EINTR有所准备。...如果该函数返回EINTR,我们就不能再次调用它,否则将立即返回一个错误。当connect被一个捕获信号中断而且不自动重启时,我们必须调用select来等待连接完成。...即SO_RCVTIMEO和SO_SNDTIMEO会导致read/write函数返回EAGAIN 另外,在确定错误过程中,同事提到O_NODELAY会导致write接口返回EAGAIN,的确,如果设置了O_NODELAY...而当前不可写,那么write接口会设置errno为EAGAIN,但是write接口会返回0而不是-1.在本案中,hiredis接口中并没有设置O_NODELAY 参考链接 阻塞socket上read/write

    1.1K20

    面试官:Java Nio优缺点?可能瓶颈有哪些?

    NIO中 N 可以理解为 Non-blocking,同步非阻塞IO。...NIO 这两种通道都支持阻塞和非阻塞两种模式阻塞模式使用就像传统中支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式有较好性能和可靠性。...选择器(Selector): 选择器是用于多路复用 I/O 组件,可以通过一个线程管理多个通道。 选择器可以同时监控多个通道上事件,如读取事件、写入事件等。...方法是阻塞方法, 只有找到匹配channel之后才会返回,为了多次进行select操作,我们需要在一个while循环里面进行selectorselect操作: while (true) {...NIO 可能瓶颈 使用内存占用:使用直接内存缓冲区可能导致较高内存消耗,特别是在处理大量数据时,对于内存控需要更加严格。

    57220

    recv函数说明返回

    服务端程序 固然可以 变成长连接,也就是说 当客户端与服务端 交互状态处于空闲时,比如长达5分钟。服务端就会主动关闭连接,这样可以减轻服务端压力。...默认 socket 是阻塞阻塞与非阻塞recv返回值没有区分,都是 0 接收到数据大小, 特别: 返回值<0时并且(errno == EINTR || errno...只是阻塞模式下recv会阻塞着接收数据,非阻塞模式下如果没有数据会返回,不会阻塞着读,因此需要循环读取)。 返回说明:  成功执行时,返回接收到字节数。 另一端已关闭则返回0。...失败返回-1, errno被设为以下某个值  EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时  EBADF:sock不是有效描述词  ECONNREFUSE:远程主机阻绝网络连接...:sock索引不是套接字 当返回值是0时,为正常关闭连接; 思考: 当对侧没有send,即本侧套接字s接收缓冲区无数据,返回值是什么(EAGAIN,原因为超时,待测) http://hi.baidu.com

    4.9K10

    linux epoll机制详解

    ,产生巨大开销; 3.select返回是含有整个句柄数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件; 4.select触发方式是水平触发,应用程序如果没有完成对一个已经就绪文件描述符进行...一般用-1即可 epoll工作模式 ET(EdgeTriggered):高速工作模式,只支持no_block(非阻塞模式)。在此模式下,当描述符从未就绪变为就绪时,内核通过epoll告知。...epoll工作在ET模式时候,必须使用非阻塞套接口,以避免由于一个文件句柄阻塞读/阻塞写操作把处理多个文件描述符任务饿死。...只有当read(2)或者write(2)返回EAGAIN时(认为读完)才需要挂起,等待。...但这并不是说每次read()时都需要循环读,直到读到产生一个EAGAIN才认为此次事件处理完成,当read()返回读到数据长度小于请求数据长度时(即小于sizeof(buf)),就可以确定此时缓冲中已没有数据了

    3.9K35

    Epoll

    线程B:执行 accept() 失败,accept() 返回 EAGAIN 其中,线程 B 唤醒完全没有必要,仅仅只是浪费宝贵 CPU 资源而已,水平触发模式 epoll 扩展性很差。...线程A:再次执行 accept(),这次终于返回 EAGAIN 可以看到在上面的例子中,线程 B 唤醒是完全没有必要。 另外,事实上边缘触发模式还存在饥饿问题,我们来看下面这个例子: 1....由于线程 A 还没有处理完(没有返回 EAGAIN),当前 socket 还处于可读状态,由于是边缘触发模式,所有不会产生新事件 5....线程A:又继续执行 accept(),结果又返回成功 在这个例子中个,这个 socket 只有一次从不可读状态变成可读状态,由于 socket 处于边缘触发模式,内核只会唤醒 epoll_wait()...由于 close(rfd) 关掉了这个 rfd,你可能会认为这个 epoll_wait() 会一直阻塞返回,而实际上并不是这样。

    65820
    领券