I/O复用之Select模型
I/O复用使得程序能够同时监听多个文件描述符,但是,他本身也是阻塞的,并且当一个或多个文件描述符准备就绪时,如果不采用其他措施,程序只能按顺序处理其中的每个文件描述符。如果要使程序能够并行运行,只能使用多进程或多线程的方式。
Linux下实现I/O复用的系统调用主要有select、poll和epoll,下面将详细介绍select的系统调用。
Select系统调用的用途:在一段时间内,监听用户感兴趣的文件描述符上面的可读、可写和异常等事件。
相关API的介绍:
1 2 |
|
①、nfds参数:所有监听的文件描述符的最大值 + 1
②、readfds、writefds和exceptfds参数分别为可读、可写和异常等事件对应的文件描述符集合;程序只需要传入自己感兴趣的文件描述符,内核将修改他们来通知程序那些文件描述符已经准备就绪;fd_set结构体仅包含一个整形数组,该数组的每一个元素的每一位标志一个文件描述符,下面的一组宏用来操作fd_set的每一位:
1 2 3 4 |
|
③、ttimeout参数:timeout参数是一个timeval结构体,timeval的结构体的定义如下:
1 2 3 4 5 |
|
如果tv_sec和tv_usec都设置为0,则select立即返回, 如果timeout参数设置为NULL,则select一直阻塞直到某个文件描述符准备就绪。
返回值:成功返回就绪的文件描述符的总数,如果超过时间内没有任何文件描述符准备就绪,select将返回0,失败则返回-1并设置errno;若在select等待事件内程序接收到信号,则select立即返回-1,并设置errno为EINTER。
文件描述符的就绪条件:
可读描述符就绪条件:
①、接收缓冲区中的字节数大于或等于SO_RCVLOWAT标志
‚、有新的连接请求
ƒ、对方关闭连接
④、有未处理的错误
可写描述符的就绪条件:
①、发送缓冲区中的可用字节数大于或等于SO_SENLOWAT标志
‚、写操作被关闭
ƒ、有未处理的错误
异常文件描述符的就绪条件:
①、socket上接收带外数据
代码示例:
[1].[文件] command_define.h ~ 613B 下载(71) 跳至 [1] [2] [3] [4]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
[2].[文件] TcpServer.h ~ 1020B 下载(64) 跳至 [1] [2] [3] [4]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
[3].[文件] TcpServer.cpp ~ 6KB 下载(66) 跳至 [1] [2] [3] [4]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
|
[4].[文件] test.cpp ~ 825B 下载(66) 跳至 [1] [2] [3] [4]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
分享的代码主要是使用select系统调用和多线程编程实现一个简单的并行的TCP服务器
select 模型的有缺点:
优点:select模型的优点之一就是良好的跨平台支持
缺点:
1、单个进程能够监测的文件描述符有限,一般为1024,可以通过修改内核修改
2、select维护了存储大量文件描述符的数据结构,随着文件描述符的增加,其复制的开销及遍历造成的开销影响系统效率。