C/C++ WebServer 5 项目实战与总结

Meqt

阻塞和非阻塞、同步和异步

网络IO
数据就绪

  • 阻塞
  • 非阻塞:不会改变线程的状态,通过返回值判断
    数据读写,应用程序
  • 同步
  • 异步:通知方式,更为麻烦
    在处理I/O的时候,阻塞和非阻塞都是同步I/O,只有使用了特殊的AP1 才是异步I/O。
    Linux:AIO
    Windows:IOCP

Unix、Linux上的五种IO模型

  1. Blocking
  2. Nonblocking
    EAGAIN
  3. IO multiplexing
    Select, poll, epoll
  4. Signal-driven
  5. Asynchronous

Web服务器简介及HTTP协议

HTTP 请求方法

GET
HEAD
POST
PUT
DELETE
TRACE
OPTIONS
CONNECT

服务器编程基本框架和两种高效的事件处理模式

逻辑处理
模块:
I/O处理单元
逻辑单元:业务线程或进程(并发处理)
网络存储单元:数据库、文件或缓存
请求队列:各单元之间的通信方式
三类事件
I/O事件,信号及定时事件
两类事件处理模式:
Reactor模式:
主线程:监听文件描述符上是否有事件发生。工作线程
同步I/O
Proactor方式:
异步I/O模型:
将所有I/O操作都交给主线程和内核来处理,工作线程仅负责业务逻辑
采用同步I/O模拟Proactor模式

线程同步机制类封装及线程池实现

线程池是由服务器预先创建的一组子线程,线程池中的线程数应该和 CPU 数星差不多。线程池中的所有子线程都运行着相同的代码。当有新的任务到来时,主线程将通过某种方式选择线程池中的某一个子线程来为之服务。相比与动态的创建子线程,选择一个已经存在的子线程的代价显然要小得多。至于主线程选择哪个子线程来为新任务服务,则有多种方式:

  • 主线程使用某种算法来主动选择子线程。最简单、最常用的算法是随机算法和Round Robin(轮流选取)算法,但更优秀、更智能的算法将使任务在各个工作线程中更均匀地分配,从而減轻服务器的整体压力。
  • 主线程和所有子线程通过一个共享的工作队列来同步,子线程都睡眠在该工作队列上。当有新的任务到来时,主线程将任务添加到工作队列中。这将唤醒正在等待任务的子结程,不过只有一个子线程将获得新任务的接管权,已可以从工作队列中取出任务并执行之,而其他子线程将继续睡眠在工作队列上。
    对于CPU密集型的任务,线程数最最好也设置为4(或者+1防止其他因素造成的线程阻塞),对于IO密集型的任务,一般要多于CPU的核数,因为线程间竞争的不是CPU的计算资源而是IO,IO的处理一般较慢,多于cores数的线程将为CPU争取更多的任务,不至在线程处理IO的过程造成CPU空闲导致资源浪费。
  • 空间换时间,浪费服务器的硬件资源,换取运行效率。
  • 池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化,这称为静态资源。
  • 当服务器进入正式运行阶段,开始处理客户请求的时候,如果它需要相关的资源,可以直接从池中获取,无需动态分配。
  • 当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用释放资源。

定时检测非活跃连接、服务器压力测试

  • Post title:C/C++ WebServer 5 项目实战与总结
  • Post author:Meqt
  • Create time:2022-12-17 20:40:08
  • Post link:https://meqtmac.github.io/2022/12/17/WebServerNote/webserver-note5/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.