TCP并发服务器
- 单循环服务器:一次只能处理一个客户端任务的服务器
- 并发服务器:能够同时处理多个客户端任务的服务器

TCP并发服务端:
- 多进程
- 安全、资源开销大、并发量小
- 多线程
- 相对进程资源开销小,相对并发量大
- 线程池
- 提前创建好大量线程管理起来,避免反复创建线程带来时间消耗
- 生产者--消费者 设计模式
- IO多路复用
- 文件 --->>fd
- 对多个文件描述符的监测,复用一个进程。
- select
- poll
- epoll
Linux常用IO模型
阻塞IO
-
fgets()
-
read()
-
fread()
-
recv()
- 让多个IO具有先后顺序
- 节省CPU资源

非阻塞IO
- 搭配轮询方式实现
- 浪费CPU资源

信号驱动IO
-
效率高
-
驱动的信号个数有限,应用层无法区分多个IO事件

IO多路复用
- 在一个进程中,同时监测多个IO
- select
- poll
- epoll

- 创建文件描述符集合
- 添加需要监测的文件描述符到集合
- 通知内核开始监测
- 由IO事件到达时,监测返回结果
select:

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
功能:通知内核监测文件描述符中的事件
参数:
nfds :集合中最大的文件描述符+1
readfds:读事件的文件描述符集合
writefds:写事件的文件描述符集合
exceptfds:其他
timeout:超时时间
NULL :不设置超时时间(阻塞)
返回值:
成功:返回到达事件的个数
失败:-1
void FD_CLR(int fd, fd_set *set);
功能:将fd对应文件描述符清零
int FD_ISSET(int fd, fd_set *set);
功能:判断fd对应的文件描述符是否被置位
void FD_SET(int fd, fd_set *set);
功能:将集合表中的fd对用的文件描述符置位
void FD_ZERO(fd_set *set);
功能:将集合表全部清零
select的特点:
- select使用数组(位图)保存文件描述符集合,最多允许监测1024个文件描述符
- select将集合表创建在应用层,需要应用层和内核层的反复数据拷贝
- select需要遍历寻找到达的IO事件,效率低
- select只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式)
poll的特点:
- poll使用链表保存文件描述符集合,理论上没有文件描述符限制
- poll将集合表创建在应用层,需要应用层和内核层的反复数据拷贝
- poll需要遍历寻找到达的IO事件,效率低
- poll只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式)
epoll的特点:
-
epoll使用树形结构保存文件描述符集合(红黑树)
-
epoll将结合表直接创建在内核层,避免应用层和内核层的反复数据拷贝
-
epoll直接返回到达的事件,不需要应用层遍历查找
-
epoll可以工作在水平触发模式(低速模式),也可以工作在边沿触发模式(高速模式)
int epoll_create(int size);功能:创建文件描述符集合
参数:
size:监测的文件描述符的最大上限
返回值:
成功:返回集合代表的文件描述符
失败:-1int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);功能:对epoll的文件描述符集合进行操作
参数:
epfd:文件描述符集合
op:操作指令
EPOLL_CTL_ADD:添加
EPOLL_CTL_MOD:修改
EPOLL_CTL_DEL:删除
fd:需要操作的文件描述符
event:事件类型
返回值:
成功:0
失败:-1typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }; int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);功能:通知内核开始监测文件描述符集合并等待返回监测到的事件结果
参数:
epfd:文件描述符集合
events:保存到达事件的数组
maxevents:监测的事件最大个数
timeout :超时时间
-1 :不设置超时
返回值:
成功:返回到达事件的个数
失败:-1