也谈如何写一个Webserver(三)

  在上一篇里,我介绍了如何应用socketepoll来组织和管理从客户端(如,浏览器)传入的连接,通过设置非阻塞连接让Webserver有更好的性能.

 

  下面,我介绍一下在我写的Webserver Maestro用的线程池.Maestro整体的结构是epoll轮询加上线程池处理传入连接中携带的http message.虽然线程池是和连接一起使用的,但其实它应该是一个独立可以处理任何任务的实体,所以,在实现时,合理的设计是可以提升应用的整体性能的.网上有很多通过简单轮询或单一队列控制的线程池,但这些线程池都不能自动伸缩来实时调整所使用的资源.虽然他们很好用,但我还是希望能更好的利用资源,动态调整线程数目,所以我选用了其他的设计思路.我采用的线程池采用的设计是,由一个Master线程控制和监控多个工作线程的方式,好处是能够根据Workload增加或减少工作线程的数目,有更好的伸缩性,更有效地利用硬件资源(CPU,内存).

 

整个线程池只有三个函数:

 

hpool_t *thpool_new(int size);

void thpool_delete(thpool_t *p);

void thpool_add_task(thpool_t *p,
                     void (*routine)(void *),
                     void *arg);

 

使用起来也是非常简单,先用thpool_new()初始化,然后通过thpool_add_task()加入需要执行的任务;使用完毕后,再通过thpool_delete()将线程池销毁.

 

  如果读者看过了thpool.c里相应的实现,可能会比较疑惑,因为会看到类似内核链表的东西.其实,大家不用太理会这些宏,他们只是借来用用而已,整个线程池仍然应该是user space的,这些宏只是用来提升性能用的,不会影响的整个线程池的设计逻辑.大家只需知道怎么用这个线程池的三个函数就可以了.

 

  我会在第四篇内容里介绍现在流行JWT(Json Web Token)在Webserver中的应用...

 

上一篇:学习Tomcat(七)之Spring内嵌Tomcat


下一篇:[Shader] 固定管线Shader01