打开文件上限的设置可修改配置文件: etc/security/limits.conf
水平、边沿触发:
若客户端发送1000B数据,服务器一次只读500B。在水平触发的模式下,服务器会再调用一次epoll_wait将剩余的数据读取。而在边沿触发模式下,服务器只会调用第一次epoll_wait,读取第一次的500B数据,剩余的数据会保留在sock可读缓存区内。
- 边沿触发:对同一次事件的epoll_wait,即使事件没处理干净,也只会有一次返回值
- 水平触发:对同一次时间的epoll_wait,即使事件没处理干净,下一次epoll_wait也会有返回值
- 水平触发的设置:event.events=EPOLLIN (默认)
- 边沿触发的设置:event.events=EPOLLIN|EPOLLET
反应堆模型:
- 监听可读事件(ET) ⇒ 数据到来 ⇒ 触发事件 ⇒ epoll_wait()返回 ⇒读取完数据(可读事件回调函数内) ⇒ 将该节点从红黑树上摘下(可读事件回调函数内) ⇒ 设置可写事件和对应可写回调函数(可读事件回调函数内) ⇒ 挂上树(可读事件回调函数内) ⇒ 处理数据(可读事件回调函数内)⇒ 监听可写事件(ET) ⇒ 对方可读 ⇒ 触发事件 ⇒ epoll_wait()返回 ⇒写完数据(可写事件回调函数内) ⇒ 将该节点从红黑树上摘下(可写事件回调函数内) ⇒ 设置可读事件和对应可读回调函数(可写读事件回调函数内) ⇒ 挂上树(可写事件回调函数内) ⇒ 处理收尾工作(可写事件回调函数内) ⇒ 直到程序停止前一直这么交替循环
- 至此,结束
线程池:
- 线程池就是有一堆已经创建好了的线程,初始它们都处于空闲等待状态,当有新的任务需要处理的时候,就从这个池子里面取一个空闲等待的线程来处理该任务,当处理完成了就再次把该线程放回池中,以供后面的任务使用。当池子里的线程全都处理忙碌状态时,线程池中没有可用的空闲等待线程,此时,根据需要选择创建一个新的线程并置入池中,或者通知任务线程池忙,稍后再试。这种方式避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。
组成部分
- 线程管理者
- 等待任务的线程
- 任务队列