首页 > Web开发 > 详细

SbWebServer的几个设计

时间:2019-09-17 01:05:46      阅读:148      评论:0      收藏:0      [点我收藏+]

基于生产者消费者模型的线程池设计:

数据结构:

成员:

1.一个队列m_queue.其中存放Task,也就是任务,生产者线程,也就是主线程,往这个队列中push;消费者,也就是工作线程,不停地从其中拿走Task去工作。

关于Task,原型为boost::function<void()> Task;

2.一个表示线程数量的变量m_threadNum

3.一个表示队列,即流水线的最大长度变量m_maxSize

4.一个互斥量m_mutex,用于条件变量判断时对队列的状态进行保护

5.一个条件变量m_notFull,用于通知唤醒消费者线程

6.一个条件变量m_notEmpty,用于通知唤醒生产者线程

函数:

1.线程池构造函数ThreadPool(int threadNum,int maxSize)

threadNum为线程数量,maxSize为队列最大大小

在构造函数中创建threadNum个工作线程

2.静态函数startThread

工作线程实际上的工作内容,创建的工作线程从startThread开始工作。

首先pthread_detach,分离后线程的资源自动回收,不用join

startThread中传入线程池的this指针,这样静态函数startThread可以通过这个this指针调用线程池中的Work函数,Work才是真正的线程工作的主体

3.Work函数

Work内是一个for循环f(;;),循环内调用函数Take()从线程池的队列中取走任务,如果取来的任务可用,则执行这个任务

4.Take函数
典型的生产者消费者模型,首先用m_mutex加锁,加锁保护当前队列状态的原子性,用while(m_queue.empty())判断流水线中是否有工作,如果没有则wait陷入沉睡,直到生产者唤醒

如果有工作,则拿走,并返回这个Task;Work函数拿到这个Task后执行这个任务

5.append函数

参数传入bind的function

典型的生产者消费者模型,用于生产者往流水线中添加任务。依然是mutex加锁保护队列的状态,如果非满则将这个function加入到队列中

页面缓存设计

缓存Cache:
数据成员:

一个哈希表unordered_map:key为页面名,作为key;value为一个shared_ptr指针,指向FileInfo,FileInfo为封装了页面mmap到内存的类

一个互斥锁mutex,用于缓存满了删除时保证原子性

函数:

1.getFile用于在页面缓存中寻找请求的资源。

首先加锁,防止请求资源时该缓存被淘汰而出现问题。然后在哈希表中用文件名去寻找,如果未找到,则将这个页面加入缓存。如果此时缓存已满,则淘汰掉访问次数较少的页面,访问次数的统计被封装在FileInfo中。

2.清楚缓存的函数cleancache:

遍历哈希表,如果访问次数小于10的页面均淘汰掉。

 

页面封装FileInfo:

数据成员:

1.存储 通过mmap映射到内存的地址 的变量addr:所访问的页面都通过mmap映射到内存,然后记录这个地址,封装到FileInfo中,这样每次打开就不用了重新IO打开文件,只要通过这个文件对应的FileInfo中的addr即可寻址到页面对应的位置

2.size表示文件的大小

3.count用于统计页面的访问次数,当缓存满时以此为基准进行淘汰

方法:

1.构造函数:通过文件名打开对应文件,然后使用mmap将之映射到内存,mmap返回的结果赋予addr,用于寻址

2.析构函数:munmap来释放映射到内存的内容。当然,析构的时间由shared_ptr来掌握

 

SbWebServer的几个设计

原文:https://www.cnblogs.com/lxy-xf/p/11531182.html

(1)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!