1.select函数允许进程指示内核等待多个事件中的任何一个发生,并且在只有一个或多个事件发生或经历一段时间后才唤醒进程(函数返回)。函数原型为:int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set * exceptset,const struct timeval *timeout)。第一个参数maxfdp1是指所有监听的描述符中编号最大的符号加一,即如果最大的描述符是5,则maxfdp1是6;第二个参数是监听的读取的描述符的集合;第三个参数是监听的写操作的描述符的集合;第四个参数是监听的异常的描述符的集合;第五个是一个时间结构体,用于表示超时,即如果超过那个时间还没有描述符符合条件,函数也返回。
2.第二三四个参数如果不需要进行使用的时候,可以赋值为NULL;如果第二三四个参数都是NULL,这个函数可以作为一个比sleep更精确的定时器,因为timeout参数包含秒和微妙的参数。
3.关于最后一个时间参数,如果赋值为空指针,那么就意味着永远等待下去,不会因为超时而返回。
4.函数返回之后,可以通过FD_ISSET函数检查一个描述符是否符合条件进行I/O操作了。值得注意的是,readset,writeset和exceptset都是值-结果参数,意思就是既作为一个值传进去,也会因为被修改而作为一个结果返回。每次调用select都需要调用FD_SET来填充需要监听的描述符。
5.关于shutdown函数和close函数:close函数只是把引用计数减1,仅在引用计数为0的时候关闭套接字;而shutdown就不管引用计数直接激发TCP的正常连接终止序列。close函数终止读和写两个方向的数据传送,而shutdown可以选择终止连接的方式(断开读,断开写,两个都断开)。
6.select的优点之一是,对于需要处理多个连接,不需要对每一个连接都fork一个子进程,而是用select来选择出符合I/O条件的套接字进行I/O操作,这样可以节省资源。