I/O复用之select与pselect

【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数 本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程。I/O复用适用于以下场合:(1) 当客户处理多个描述符(一般是交互式输入或网络套接字),必须适用I/O复用(2) 当一个客户处理多个套接字时,这种情况很少见,但也可能出现(3) 当一个TCP服务器既要处理监听套 阅读详情

IO复用概念

有些进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或者多个I/O条件就绪(即是说,输入已经准备好读取,或者,描述字已经能承接更多的输出),它就通知进程,这个能力就成为I/O复用,是由select和poll这两个函数支持的。其中,关于poll的讲解可以参考http://blog.youkuaiyun.com/pngynghay/article/details/17327179。另外,select和poll的增强版本epoll模型,可以参考http://blog.youkuaiyun.com/pngynghay/article/details/8169455

典型的网络应用场合

  • 当客户端需要处理多个描述字(通常是交互式输入和网络套接口)时,必须使用IO复用。
  • 一个客户同时处理多个套接口是可能的,不过,比较少见。
  • 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般就要哦使用IO复用。
  • 如果一个服务器既要处理TCP,又要处理UDP,一般要使用IO复用。
  • 如果一个服务器要处理多个服务或者多个协议,一般就要使用IO复用。

注:IO复用并非只限于网络编程。

select函数

函数原型

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout)

返回值:就绪描述字的正数目,0表示超时,-1表示你出错

参数:

maxfdpl:指定待测试的描述字个数,它的值是待测试的最大描述字加1(因为描述字是从0开始的);select.h中定义的FD_SETSIZE是数据类型fd_set中的描述字总数,通常为1024。

readset:读集合

writeset:写集合

exceptset:异常集合

timeout:告知内核等待所指定描述字中的任何一个就绪可花多长时间,timeval结构体用于指定这段时间的秒数和微秒数。如果该参数为NULL,那么,select函数将一直等待下去,直到有描述字准备好IO返回;如果该参数不为NULL,并且timeout为0(即定时器值的微秒数和秒数均为0),那么,select检查描述字后立即返回,成为轮询;如果该参数不为NULL,且timeout不为0,那么,select等待时间不超过timeout值,且在等待期间,如果有一个IO准备就绪,select也立即返回。

 

该函数允许进程指示内核等待多个事件中 的任何一个发生,并仅在有一个或者多个事件发生或者经历一段指定的时间后才唤醒它。我们调用select函数告诉内核对哪些描述字感兴趣以及等待多长时间。

注:我们感兴趣的描述字不局限于套接口,任何描述字都可以使用select来测试。

利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据。目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫进入阻塞状态。

 

fd_set是一个SOCKET队列,以下宏可以对该队列进行操作:

FD_CLR( s, *set) 从队列set删除句柄s;

FD_ISSET( s, *set) 检查句柄s是否存在与队列set中;

FD_SET( s, *set )把句柄s添加到队列set中;

FD_ZERO( *set ) 把set队列初始化成空队列.

 

注:select函数的三个fd_set参数所指向的描述字集,都是值-结果参数。调用该函数时,我们指定所关心的描述字的值,该函数返回时,结果表示哪些描述字已经准备就绪。该函数返回后,我们使用FD_ISSET宏来测试fd_set数据类型中的描述子。描述字集中任何与未就绪的描述字想对应的位均清0,为此,每次重新调用select函数时,我们都得再次把我们感兴趣的所有描述字集的位置1.

 

附Linux man部分信息

NAME
       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous I/O multiplexing

SYNOPSIS
       /* According to POSIX.1-2001 */
       #include <sys/select.h>

       /* According to earlier standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

       #define _XOPEN_SOURCE 600
       #include <sys/select.h>

       int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);

DESCRIPTION
       select()  and pselect() allow a program to monitor multiple file descriptors, waiting until one or
       more of the file descriptors become "ready" for some class of I/O operation  (e.g.,  input  possi-
       ble).   A  file  descriptor is considered ready if it is possible to perform the corresponding I/O
       operation (e.g., read(2)) without blocking.

       The operation of select() and pselect() is identical, with three differences:

       (i)    select() uses a timeout that is a struct timeval (with  seconds  and  microseconds),  while
              pselect() uses a struct timespec (with seconds and nanoseconds).

       (ii)   select()  may  update  the  timeout argument to indicate how much time was left.  pselect()
              does not change this argument.

       (iii)  select() has no sigmask argument, and behaves as pselect() called with NULL sigmask.

       Three independent sets of file descriptors are watched.  Those listed in readfds will  be  watched
       to  see  if  characters  become  available  for reading (more precisely, to see if a read will not
       block; in particular, a file descriptor is also ready on end-of-file), those in writefds  will  be
       watched  to  see if a write will not block, and those in exceptfds will be watched for exceptions.
       On exit, the sets are modified in place to indicate which file descriptors actually  changed  sta-
       tus.   Each  of the three file descriptor sets may be specified as NULL if no file descriptors are
       to be watched for the corresponding class of events.

       Four macros are provided to manipulate the sets.  FD_ZERO() clears a set.  FD_SET()  and  FD_CLR()
       respectively add and remove a given file descriptor from a set.  FD_ISSET() tests to see if a file
       descriptor is part of the set; this is useful after select() returns.

       nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

       timeout is an upper bound on the amount of time elapsed before select() returns. It may  be  zero,
       causing select() to return immediately. (This is useful for polling.) If timeout is NULL (no time-
       out), select() can block indefinitely.

       sigmask is a pointer to a signal mask (see sigprocmask(2)); if it  is  not  NULL,  then  pselect()
       first  replaces  the  current signal mask by the one pointed to by sigmask, then does the ‘select’
       function, and then restores the original signal mask.

       Other than the difference in the precision of the timeout argument, the following pselect() call:

           ready = pselect(nfds, &readfds, &writefds, &exceptfds,
                           timeout, &sigmask);

       is equivalent to atomically executing the following calls:

           sigset_t origmask;

           sigprocmask(SIG_SETMASK, &sigmask, &origmask);
           ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
           sigprocmask(SIG_SETMASK, &origmask, NULL);

       The reason that pselect() is needed is that if one wants to wait for either a signal or for a file
       descriptor  to  become  ready, then an atomic test is needed to prevent race conditions.  (Suppose
       the signal handler sets a global flag and returns. Then a test of this global flag followed  by  a
       call of select() could hang indefinitely if the signal arrived just after the test but just before
       the call.  By contrast, pselect() allows one to first block signals, handle the signals that  have
       come in, then call pselect() with the desired sigmask, avoiding the race.)

   The timeout
       The time structures involved are defined in <sys/time.h> and look like

         struct timeval {
             long    tv_sec;         /* seconds */
             long    tv_usec;        /* microseconds */
         };

       and

         struct timespec {
             long    tv_sec;         /* seconds */
             long    tv_nsec;        /* nanoseconds */
         };

       (However, see below on the POSIX.1-2001 versions.)

       Some  code  calls  select()  with all three sets empty, n zero, and a non-NULL timeout as a fairly
       portable way to sleep with subsecond precision.

       On Linux, select() modifies timeout to reflect the amount of time not slept; most other  implemen-
       tations  do not do this.  (POSIX.1-2001 permits either behaviour.)  This causes problems both when
       Linux code which reads timeout is ported to other operating systems, and when code  is  ported  to
       Linux  that  reuses  a  struct timeval for multiple select()s in a loop without reinitializing it.
       Consider timeout to be undefined after select() returns.

RETURN VALUE
       On success, select() and pselect() return the number of file descriptors contained  in  the  three
       returned  descriptor  sets  (that  is, the total number of bits that are set in readfds, writefds,
       exceptfds) which may be zero if the timeout  expires  before  anything  interesting  happens.   On
       error,  -1  is returned, and errno is set appropriately; the sets and timeout become undefined, so
       do not rely on their contents after an error.

ERRORS
       EBADF  An invalid file descriptor was given in one of the sets.  (Perhaps a file  descriptor  that
              was already closed, or one on which an error has occurred.)

       EINTR  A signal was caught.

       EINVAL nfds is negative or the value contained within timeout is invalid.

       ENOMEM unable to allocate memory for internal tables.

 

服务器程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/time.h>

/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>


#define MAXLINE 1024
#define SERV_PORT 5000
#define LISTENQ 100 

void err_quit(char * msg)
{
        printf("err %s", msg);
        exit(0);
}

int main(int argc, char **argv)
{
        int i, maxi, maxfd, listenfd, connfd, sockfd;
        int nready, client[FD_SETSIZE];
        ssize_t n;
        fd_set rset, allset;
        char buf[MAXLINE];
        socklen_t clilen;
        struct sockaddr_in cliaddr, servaddr;

        listenfd = socket(AF_INET, SOCK_STREAM, 0);

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port        = htons(SERV_PORT);

        bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

        listen(listenfd, LISTENQ);

        maxfd = listenfd;                       /* initialize */
        maxi = -1;                                      /* index into client[] array */
        for (i = 0; i < FD_SETSIZE; i++)
                client[i] = -1;                 /* -1 indicates available entry */
        FD_ZERO(&allset);
        FD_SET(listenfd, &allset);
        /* end fig01 */

        /* include fig02 */
        for ( ; ; ) {
                rset = allset;          /* structure assignment */
                nready = select(maxfd+1, &rset, NULL, NULL, NULL);

                if (FD_ISSET(listenfd, &rset)) {        /* new client connection */
                        clilen = sizeof(cliaddr);
                        connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
#ifdef  NOTDEF
                        printf("new client: %s, port %d\n",
                                        inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL),
                                        ntohs(cliaddr.sin_port));
#endif

                        for (i = 0; i < FD_SETSIZE; i++)
                                if (client[i] < 0) {
                                        client[i] = connfd;     /* save descriptor */
                                        break;
                                }
                        if (i == FD_SETSIZE)
                                err_quit("too many clients");

                        FD_SET(connfd, &allset);        /* add new descriptor to set */
                        if (connfd > maxfd)
                                maxfd = connfd;                 /* for select */
                        if (i > maxi)
                                maxi = i;                               /* max index in client[] array */

                        if (--nready <= 0)
                                continue;                               /* no more readable descriptors */
                }

                for (i = 0; i <= maxi; i++) {   /* check all clients for data */
                        if ( (sockfd = client[i]) < 0)
                                continue;
                        if (FD_ISSET(sockfd, &rset)) {
                                if ( (n = read(sockfd, buf, MAXLINE)) == 0) {
                                        /*4connection closed by client */
                                        close(sockfd);
                                        FD_CLR(sockfd, &allset);
                                        client[i] = -1;
                                } else
                                        write(sockfd, buf, n);

                                if (--nready <= 0)
                                        break;                          /* no more readable descriptors */
                        }
                }
        }
}

关系到套接字列表的操作都需要使用循环,在轮询的时候,需要遍历一次,再新的一轮开始时,将列表加入队列又需要遍历一次.也就是说,Select在工作一次时,需要至少遍历2次列表,这是它效率较低的原因之一.在大规模的网络连接方面,还是推荐使用IOCP或EPOLL模型.但是Select模型可以使用在诸如对战类游戏上,比如类似星际这种,因为它小巧易于实现,而且对战类游戏的网络连接量并不大.

 客户端程序同 http://blog.youkuaiyun.com/pngynghay/article/details/8169455中的客户端程序

8、Linux 多路复用 I/O 与内核 I/O 实现详解 本文详细解析了Linux系统中的多路复用I/O机制,包括select、poll及其变体pselect和ppoll的使用方法和工作原理,并深入探讨了Linux内核的I/O实现,如虚拟文件系统(VFS)、页面缓存和页面回写机制。同时,文章对select和poll进行了比较,分析了各自的优缺点,并提供了I/O性能优化的实用建议。通过这些内容,开发者可以更好地理解和应用Linux中的多路复用I/O技术,优化应用程序的性能与稳定性。 阅读详情

相关推荐

8、Linux 多路复用 I/O 技术详解

本文深入详解了Linux中多路复用I/O技术,包括其工作原理、常用的系统调用(如select、poll、pselect、ppoll)的使用方法及特点,并对它们的优缺点进行了对比分析。同时,文章还介绍了多路复用I/O技术的应用场景、性能优化建议以及常见错误处理方法。通过本文,开发者可以全面了解并合理应用多路复用I/O技术以提升程序性能和资源利用率。

nn3456的博客 112

Linux网络编程--select()和pselect()函数

函数select()与之前的recv()和send()直接操作文件描述符不同。使用select()函数可以先对需要操作的文件描述符进行查询,查看是否目标文件描述符可以进行读、写或者错误操作,然后当文件描述符满足操作的条件的时候才进行真正的IO操作。函数select()是用一种超时轮循的方式来查看文件的读写错误可操作性。在Linux下,还有一个相似的函数pselect()。函数select()和pselect()用于IO复用,它们监视多个文件描述符的集合,判断是否有符合条件的时间发生。...

木牛的博客 1043

Clion+platformIO开发ESP32时找不到lib文件中引入第三方库的头文件(头文件下有波浪线),实际编译是成功的解决方法

Clion+platformIO开发ESP引入第三方库文件编译器无法找到.h文件但编译成功

zs5218的博客 1852

Linux中pselect实例,linux select pselect poll epoll用法

8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?#include #include #include #include void FD_CLR(int fd, fd_set *set);int FD_ISSET(int fd, fd_set *set);void FD_SET(int fd, fd_set *set);void FD_ZERO(fd_set *set...

weixin_33518565的博客 309

QSPI Flash的原理与QSPI时序的Verilog实现

本节主要是讨论QSPI(Quad SPI,四线SPI总线)的相关内容。我的开发板上有一片型号是W25Q128BV的Quad SPI Flash存储器,本文将以它为例子来说明QSPI操作的一些内容。

Go Forward Forever! 4165

AD9026芯片开发实战:从Example Code到API调用的关键步骤解析

本文详细解析了AD9026芯片开发的核心流程,重点阐述了如何从官方提供的Example Code入手,逐步理解硬件平台发现、HAL层初始化、配置加载、芯片复位、固件启动、JESD链路建立等关键API调用序列。通过剖析示例工程的结构与核心文件,为开发者在自定义硬件平台上移植和调试AD9026驱动提供了清晰的实战指南。

java5的博客 788

linux-select函数详解

linux-select函数详解

weixin_37515325的博客 1790

STM32F103ZET6【标准库函数开发】------04五个串口配置实战:从零到一构建多串口通信系统

本文详细介绍了STM32F103ZET6标准库函数开发中五个串口(USART/UART)的配置实战,从硬件引脚识别、时钟树配置到多串口系统整合技巧。通过具体代码示例和调试经验,帮助开发者快速构建稳定的多串口通信系统,适用于工业控制、物联网网关等应用场景。

weixin_29188997的博客 344

【Linux C | I/O模型】IO复用 | select、pselect函数详解及例子代码(看完就会用了)

👉本文先是介绍select函数,然后介绍使用select的步骤,并给出了使用select的C语言例子,最后介绍了pselect函数并给出C语言使用例子。

wkd_007的博客 3067

滑模控制理论(SMC)概述

滑模控制理论(SMC)概述一、背景二、数学理论三、高维拓展四、分析 一、背景 滑模控制理论(Sliding Mode Control, SMC)是一种建立在现代控制理论基础上的控制理论,主要数学核心为李雅普诺夫函数。 滑模控制的核心思想是建立一个滑模面,将被控系统拉取到滑模面上来,使系统沿着滑模面运动。滑模控制的一个优势是无视外部扰动和不确定参数,采用一种比较“暴力”的方式达到控制的目的。 其思想和反步法有些类似,但数学实现起来更加方便而不抽象。相比反步法,滑模控制没有复杂的数学计算,也不会出现“微分爆炸”

高能阿博特的博客 6万+

海康视觉平台VisionMaster使用学习笔记(1)

双击图像源设置图像源的属性,像素格式分为Mono8和RDB24分别对应导入的图像是彩色还是黑白。打开相机驱动软件MVS,对连接的相机进行属性上的配置,先对相机的IP进行对应的设置。将自动触发的使能打开,保存配置好的相机属性,默认保存到用户集1中。点击MVS软件中的触发按钮,查看相机是否进行正常的触发拍照。打开VM软件添加一个图像源,选择图像源选项拖出图像源。回到VM软件中将选择相机选项选择到配置好参数的相机。取图方式也可以调整为相机取图,将图像源改为相机。双击相机进行连接后对相机的属性进行配置。

A567852的博客 1万+

I/O复用:select、poll、pselect和epoll

一 I/O模型: (1)阻塞式I/O:最常用的I/O模型。默认情况下,所有套接字都是阻塞的。 (2)非阻塞式I/O:不把进程投入睡眠,而是返回一个错误。 (3)I/O复用:调用select或poll,阻塞在这两个系统调用中的某一个之上,而不是阻塞在真正的I/O系统调用上。 (4)信号驱动I/O:让内核在描述符就绪时发信号通知进程。优势:等待数据到达期间进程不被阻塞。 (5)异步I/O:告

linux系统、网络编程和分布式计算 2119

6、高通8155座舱平台--摄像头系统

在项目中遇到过,很多从手机转过来的工程师,上来就按手机那套调Camera,结果发现根本跑不通——为什么?我踩过这个坑——一开始想靠软件打时间戳来对齐,结果发现两个sensor的曝光时间不一样,时间戳根本对不上。我记得第一次调AWB时,怎么调颜色都不对,后来发现是BLC的参数没配好——黑电平偏了,后面所有颜色校正都是错的。上层应用说「我要拍张照」,HAL把它翻译成「ISP你给我处理这帧数据,sensor你给我曝光一次」。8155上推荐用camx,它是高通新一代的Camera框架,性能更好,而且支持多路同步。

woailuojp的博客 58

I/O多路复用详解

<br />转自:http://konglingchun.is-programmer.com/posts/12146.html<br /> <br />要想完全理解I/O多路复用,需先要了解I/O模型: <br />一、五种I/O模型<br />1、阻塞I/O模型<br />     最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的。我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原因在于就UDP而言,数据准备好读取的概念比较简单:要么整个数据报已经收到,要么还

1968

App 抓包难?Frida Hook 实战:绕过 SSL Pinning (证书绑定) 抓取某大厂 App 核心接口

当我们使用 Charles 抓包 HTTPS 时,本质上是实施了MITM(中间人攻击)。Charles 伪装成服务器,发给 App 一个自己的证书(伪造证书)。Charles 伪装成 App,拿着真正的证书去请求服务器。如果 App 只是简单校验“证书是否由受信任的 CA 签发”,那你把 Charles 的根证书安装到手机系统里,就能骗过它。但是,是 App 内置了服务器证书的Hash(指纹)。

BUG猿的博客 914

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Linux】I/O多路复用—select和pselect

select函数 #include &lt;sys/select.h&gt; int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr); 返回...

萧十一的技术小站 1044

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

I/O复用(I/O multiplexing): select, pselect, poll, ppoll, epoll

日期:2016.05.30 作者:i.sshe https://github.com/isshe I/O复用:select, pselect, poll, epoll. 注意:本文主要介绍的是epoll相关知识,无法确保正确 1. 相关问题: 1.1 什么是I/O复用? 1.2 四个I/O复用方法相关知识点? 1.3 四个I/O复用方法的比较? 1.4 epoll有哪些触发模式?有何区别? 1.5

i.sshe的博客 1070

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

UNIX编程专题-I/O复用:select、pselect、poll和epoll解析

1.什么是I/O复用 进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(输入已准备好被读取,或者描述符已能承接更多的输出),就会通知进程。这个能力称为I/O复用。 2.I/O复用的应用场合 当客户同时处理多个描述符(通常是交互式输入和网络套接字)时,必须使用I/O复用一个客户同时处理多个套接字是可能的如果一个TCP服务器既要处理监听套接字,又要处理已连接

tiankong_的博客 2305

嵌入式Linux网络编程,I/O多路复用,阻塞I/O模式,非阻塞I/O模式fcntl()/ioctl(),多路复用I/O select()/pselect()/poll(),信号驱动I/O

文章目录1,I/O模型2,阻塞I/O 模式2.1,读阻塞(以read函数为例)2.2,写阻塞3,非阻塞模式I/O3.1,非阻塞模式的实现(fcntl()函数、ioctl() 函数)3.1.1,fcntl( )函数3.1.2,ioctl() 函数4,多路复用I/O4.1,实现多路复用 select()/poll()4.1.1,实现多路复用 select()4.1.2,另外的函数:pselect()/...

m0_37542524的博客 926

unix/linux - select and pselect Functions

select and pselect Functions1, select and pselect Functions2, man manual of select1, select and pselect Functions2, man manual of select 1, select and pselect Functions 2, man manual of select 1, select and pselect Functions The select function lets us do

天使之翼 531

I/O复用模型之select

在编程中我们用到最多的是阻塞式I/O模型。例如,进程调用recvfrom,它直到数据报到达后从内核缓冲区复制到进程缓冲区才返回。若没有数据报到达,或者没有复制到进程缓冲区,recvfrom将一直阻塞。也有可能被信号中断,而返回。例如进程调用fgets,直到用户输入回车后才后返回。否则将一直阻塞。 而I/O复用模型在一定程度上可以解决这样的问题。什么是I/O复用呢? 编程时要同时处理多个

null 1884

UNP第一卷第六章--I/O 复用:select 和 poll 函数

本文系统介绍了Unix系统的五种I/O模型及其实现方式。重点分析了阻塞式I/O、非阻塞式I/O、I/O复用(select/poll)、信号驱动式I/O和异步I/O的工作原理与区别,详细讲解了select和poll函数的应用场景、参数设置及实现细节。通过TCP回射服务器的示例,展示了如何使用select/poll实现单进程处理多客户端连接,并探讨了批量输入、半关闭(shutdown)、拒绝服务防护等关键问题的解决方案。文章还比较了select与pselect、poll的异同,总结了各种I/O模型的适用场景和选

qq_45964785的博客 685

Linux——I/O复用

<br /> <br />缅怀Stevens大师。最好的参考资料:<br />1.师从互联网。<br />2.UNP v1第6章 。<br />3,man select、man pselect、man epoll、man poll第一条:概述<br />复用是个伟大的概念呀!什么是I/O复用(I/O multiplexing)呢?具体点就是当你编写的程序需要同时处理多个描数字(socket或file或device),你又不知道什么时候应该(比方说有数据可以读了)去操作(读/写)哪个描数字。这时候I/O复用就

I am firo,I am here for you. 2288
上一篇: 磁盘接口及其适用类型
下一篇: 求数组中和为给定数所有的组合
IT_Linux
博客等级 码龄14年 31粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值