0x01 缘由
在开发过程中,某些业务场景可能要使用到进程池或者线程池。主要目标是消除动态创建进程或进程时的开销。一般如果能够准确预测自己每个进程或进程的职责,这个都是在程序启动时就创建的,后期不会动态的去创建线程池或进程池。今天主要从几个方面来学习和探讨进程池或线程池技术。
0x02 场景
常见的web服务器(需要处理较多的并发请求):
常见的lighttpd/nginx等web服务器,以及常见缓存系统。
常见的server端(游戏、直播等行业):
要处理大量的并发请求,要减小响应延迟。
0x03 设计
1、介绍
进程池作为一个服务的基础组件需要考虑如下内容:1、可配置(进程容量)。2、动态扩容(到达负载是不是可以扩容?)。3、进程池相关操作。
常规进程池模型:
进程池中的所有子进程都运行着相同的代码,并具有相同的属性,比如优先级、PGID等。当有新的任务到来时,主进程将通过某种方式选择进程池中的某一个子进程来为之服务。
负载均衡算法:随机算法和RR算法。
主进程和子进程的同步:用队列、消息传递可以采用管道的方式。
为什么要多进程或多线程实现并发呢?如果单进程或单线程则所有的工序就只能像流水线一样干完这件才能干那件,而且整个工序完成前仅只能干一件事。
2、需求
实现一个并发CGI服务:公共网关服务。类似一个请求来了,然后做相关操作。
3、类设计
实现半同步-半异步并发服务进程池类:
数据属性:进程集合、进程状态(休眠、征用)、消息管道(与主进程通讯)、进程角色、进程序号。
操作属性:构造函数(创建进程池)、运行主进程、运行子进程、子进程的处理方法。
设计思想:单例模式。
网络架构:epoll模式。
设计要求:能适配各种类型的操作。采用模板技术。
CGI服务类:
主进程:网络服务的监听。分发listen事件,如果有listen事件,则通过管道发送消息到子进程。
子进程:统一的处理过程。子进程从管道中读取到消息,进行连接,建立的连接放入队列,进行读写事件处理。
4、源码实现
源码实现注意事项:g++不支持模板申明和定义分离。
0x04 总结
此次主要在复习epoll 等API,以及设计一个类模板、进程池技术等。