高并发服务器
多路IO转接(多路IO复用): 内核监听多个文件描述符的属性(读写缓冲区)变化
如果某个文件描述符的读缓冲区变化了,这个时候就是可以读了,将这个事件告知应用层
select
监听文件描述符的存储空间变化
#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);
参数:
nfds : 最大文件描述符+1
readfds : 需要监听的读的文件描述符存放集合
writefds :需要监听的写的文件描述符存放集合 NULL
exceptfds : 需要监听的异常的文件描述符存放集合 NULL
timeout: 多长时间监听一次 固定的时间,限时等待 NULL 永久监听
struct timeval {
long tv_sec; /* seconds */ 秒
long tv_usec; /* microseconds */微妙
};
返回值: 返回的是变化的文件描述符的个数
注意: 变化的文件描述符会存在监听的集合中,未变化的文件描述符会从集合中删除
select 的优缺点
- 优点: 跨平台
- 缺点:
文件描述符1024的限制 由于 FD_SETSIZE的限制
只是返回变化的文件描述符的个数,具体哪个那个变化需要遍历
每次都需要将需要监听的文件描述集合由应用层符拷贝到内核
大量并发 少量活跃 select效率低
假设现在 4-1023个文件描述符需要监听,但是5-1000这些文件描述符关闭了?
假设现在 4-1023个文件描述符需要监听,但是只有 5,1002 发来消息- 无解
#include <stdio.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include "wrap.h"
#include <sys/time.h>
#define PORT 8888
int main(int argc, char *argv[])
{
//创建套接字,绑定
int lfd = tcp4bind(PORT, NULL);
//监听
Listen(lfd,128);
int maxfd = lfd;//最大的文件描述符,一开始是3。012已经被占用了
fd_set oldset, rset;
// 清空
FD_ZERO(&oldset);
FD_ZERO(&rset);
//将lfd添加到oldset集合中
FD_SET(lfd, &oldset);
while(1)
{
rset = oldset;//将oldset赋值给需要监听的集合rset
int n = select(maxfd+1, &rset, NULL, NULL, NULL);
if(n < 0)
{
perror("");
break;
}
else if(n