一、select()

  select的大致用法:

    fd_set fd_read, fd_write;
    struct timeval tv;

    FD_ZERO(&fd_read);
    FD_ZERO(&fd_write);

    FD_SET(sock1,&fd_read);
    FD_SET(sock2,&fd_write);

    int largest_sock = sock1 > sock2?sock1:sock2;

    tv.tv_sec = 10;
    tv.tv_usec = 0;

    int ret = select(largest_sock, &fd_read,&fd_write,NULL,&tv);

    if( ret == -1)
        // ...
    else if (ret == 0)
        // ...
    else
    {
        if( FD_ISSET(sock1,&fd_read);
            // ...
        if( FD_ISSET(sock2,&fd_write);
            // ...
    }

  select的缺点:

  1.select会修改传递的fd_set,所以每次调用完select后,fd_set将不可再复用

  2.select调用结束后,为了找出就绪的文件描述符,必须要用FD_ISSET去测试遍历整个fd_set

  3.select支持的文件描述符有限,在linux下这个数字为1024,但可以被修改

  4.当一个线程调用select()阻塞时,不能从其他线程修改fd_set.

  5.必须通过监视文件描述符的读就绪条件,才能检测到对端关闭

二、poll()

  poll()的大致用法:

    struct pollfd fds[2];

    fds[0].fd = sock1;
    fds[0].events = POLLIN;

    fds[1].fd = sock2;
    fds[1].events = POLLOUT;

    int ret = poll(&fds,2,10000);

    if( ret == -1)
        // ...
    else if( ret == 0)
        // ...
    else
    {
        if( fds[0].revents & POLLIN)
        {
             fds[0].revent = 0;
            // ...
        }
        if( fds[1].revents & POLLIN)
        {
             fds[1].revent = 0;
            // ...
        }
    }

  poll()的优点:

    1.没有文件描述符的数量限制

    2.可以复用epollfd数组

    3.可以不监视文件描述符的读就绪条件,也能发现对端socket关闭

  poll()的缺点:

    1.像select,需要遍历来发现就绪文件描述符

    2.像select,无法在being polled的时候修改epollfd

3. epoll()

  epoll()的大致    int epollfd = epoll_create1(0);    struct epoll_event ev = {0};    ev.data.ptr = pConnection1;    ev.events = EPOLLIN | EPOLLLONESHOT    epoll_ctl( epollfd, EPOLL_CTL_ADD,pConnection1->getConnection(),&ev);

    struct epoll_event pevents[20];

    int ready = epoll_wait(epollfd,pevents,20,10000);

    if( ready == -1)
        // ...
    else if( ready == 0)
        // ....
    else
    {
        for(int i =0;i<ready;i++)
        {
            // ...
        }
  }

  epoll的优点:

  1.epoll只返回就绪事件的文件描述符集合

  2.epoll允许将其他内容附加到event而不仅是文件描述符

  3.可以在任何时间添加、删除、修改event,即使线程正在调用event_wait

  4.可以允许有多个线程同时在一个epoll list中调用epoll_wait()。

12-22 20:46