-
使用C语言实现的简单http服务器
-
背景:这个作品起初(2017-6)是为了巩固linux系统编程以及网络编程编写的,只是使用了线程池+epoll来实现。在阅读了libevent还有nginx部分源码后,添加了内存池、连接和事件的处理、epoll反应堆等方面的内容,希望感兴趣的朋友可以一起交流学习。
-
开发环境:linux-3.10.0、gcc-4.8.5
-
主要功能:支持get/post请求、简单的cgi程序
该部分主要利用条件变量、互斥锁以及循环队列来实现线程池。通过将任务加入到循环队列,管理者线程当发现任务队列中有任务时,就通知各工作线程进行处理即可。
-
threadpool_create:新建一个线程池
-
threadpool_add:向线程池中添加一个任务
-
threadpool_destroy:销毁线程池
该部分参考nginx的内存池实现。主要利用了http连接的生命周期短的特性,因此不用太关心中途清理内存池,省了很多麻烦。整个内存池维护两个链表,其中一个针对小块内存,另一个针对大块内存。小块内存进行预先分配,大块内存直接由malloc动态分配。
-
ukey_create_pool():创建内存池
-
ukey_destroy_pool():销毁内存池
-
ukey_palloc():从内存池中申请内存(对齐之后)
-
ukey_pnalloc():从内存池中申请内存(不进行对齐)
-
ukey_pcalloc():从内存池中申请内存并初始化为0
-
ukey_pfree():释放内存池中的大块内存
该部分主要定义了新的数据类型(connection_t和event_t)用来管理连接以及读/写事件。每个连接对应一个读/写事件。连接由全局变量(g_manager)进行管理,它会预先分配1024个连接进行复用。并且每个事件采用回调的方式进行处理。
-
conn_init:初始化连接池
-
conn_set:设置新连接
-
conn_free:销毁指定连接(其空间并不释放,只是成员置为初始值,以便复用)
-
event_set:初始化事件
-
event_add:将事件加入epoll监听中
-
event_del:取消事件的监听
除此之外,为了方便管理线程池、内存池以及连接等资源,定义了一个全局变量g_manager
(数据类型:manager_t
)用于管理。