Webserver回顾
线程池如何工作?
从请求队列中取出request请求,然后process处理
process是处理业务代码,用于解析http请求的
如何为线程上锁
由于线程共享同一块资源,为了避免线程重复读写资源的数据安全问题
发什么信号
定义信号
信号量如何工作的?
当有一个请求添加到请求队列中时,释放信号,启动工作线程来解析这个请求。这样的话就不会还没有获得请求就启动工作线程。
run是工作线程,wait的时候阻塞在这,当释放一个信号后,就继续执行。
这里的wait和post实际上是解耦合之后的。简化了命令
在线程同步机制类里面,有互斥锁类、条件变量类、信号量类,这些都保证了所有线程能够同步进行,不会有的特别快。有点理解这个线程同步的内涵了
信号捕捉
信号量工作除了wait和post,还有信号捕捉。信号捕捉应该捕捉的就是来自系统的中断啥的
handler是一个信号处理函数的指针。
为什么一开始要忽略SIGPIPE信号?
考虑客户端异常断开的情况,那这个时候服务器再往里面写数据那就是直接退出了,在任何时候我们应该保持服务器能够一直开启而不是崩溃退出。忽略了这个情况服务器就不会未写入而崩溃,提升了健壮性。
发送信号的位置好像并不是说放在线程与线程之间,而是放在业务逻辑之间,即不同的函数当中,比如添加请求的时候,那就会释放信号,说明这个时候有请求了需要你去读了,而在线程工作的时候会等待,等到你有一个请求过来了我再去工作
所有工作线程刚被创建的时候就是就绪态了,刚被创建的时候就有回调,而run是一个死循环,线程池创建的时候,所有8个子线程就就绪工作了,只不过被wait阻塞了,一旦拿到一个信号立马就会开始工作。调用业务process()处理流程
所以说一般在最外面主函数来执行请求的获取,然后是工作线程来对请求解析执行业务逻辑。工作线程和IO线程是如此区分的。
线程池类有哪些函数?
构造、析构、append、worker、run
回调函数worker要用函数指针,void* worker(void *arg);使用静态函数
append传入了一个T*的request对象
process()是用request对象来调用的,request是线程池类的私有成员,也是
也是一个套接字
处理该传入的套接字
run中如何信号阻塞
m_queuestat是
线程池类的私有成员
而这个私有成员是线程同步类里面的信号量类
设计模式是模板方法