zoukankan      html  css  js  c++  java
  • Linux下select调用引发的血案

    Select函数使用简单,其工作原理大家通常也知道,但是在实际的使用过程中可能并没有严格遵守,而且确实也比较难以完全遵守,除非不使用它。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    Select采用一个bit表,每个fd对应表中的一个bit位,宏FD_SETSIZE为表的大小,添加到fd_set中的fd值必须小于FD_SETSIZE,否则就会越界,假设有如下一段代码:

    fd_set  readfds;

    FD_ZERO(&readfds);

    FD_SET(fd,  &readfds);

    那么,这里的fd必须满足:fd < FD_SETSIZE,否则即会发生越界,使用valgrind和purify等内存检测工具能够检测到这个问题,但通常很少人去注意,会认为是一个可以忽略的warning,其后果是导致某个不能理解的crash问题。

    通过ulimit命令和setrlimit函数来修改进程内句柄数的限制,并不会影响FD_SETSIZE的值,所以即使通过ulimit命令或setrlimit函数将进程允许的句柄改成很大了,但如果FD_SETSIZE值没有修改,则仍可能发生crash。

    在什么情况下最容易遇到这个问题?

    较容易发生在服务端程序中,因为服务端程序同一时刻的连接数很容易超过默认的FD_SETSIZE值,而服务端的代码可能是使用epoll使用的,所以它本身并不会存在问题,但是程序中可能还有个客户端,比如使用了select来实现超时连接,这个时候问题就来了,当连接数超过FD_SETSIZE时,超时连接处的select调用就发生了越界,进程就会在某个可能完全不相干的地方crash,要定位这个问题的成本是很高的,不具备一定经验,很难在短时间内定位出来。

    如何去避免这个问题了?那就是尽量不使用select,而应当使用更安全的poll函数来替代,因为poll使用的数组是调用者自己维护的,完全可以保证不越界。

  • 相关阅读:
    VS2010中连接sdf数据库的字符串 Kevin
    找不到请求的 .Net Framework Data Provider。可能没有安装 Kevin
    MVC项目中找不到 DbContext 命名空间 Kevin
    Something About Assert()——C#中的断言 Kevin
    Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction Kevin
    .NET 中的双问号 Kevin
    苹果公司一道面试题 Kevin
    The diffrence between TempData and ViewBag and ViewData Kevin
    GRUB整体分析
    忠诚的成本看房产大鳄冯仑如何处理看待忠诚
  • 原文地址:https://www.cnblogs.com/aquester/p/9891931.html
Copyright © 2011-2022 走看看