[转]网络服务器中生产者/消费者模型中的队列问题
2012-07-23 01:48
309 查看
感谢大熊同学为我解惑,这篇帖子的原创权属于大熊。
多线程模型的网络服务器中,一般有专门的网络IO线程,将请求放到请求队列中,此为生产者。然后多个工作线程从队列中获取其中一个请求,进行处理,此是消费者。
通常,通讯使用的队列为锁无关队列。且,为了避免CPU耗慢,当工作线程发现队列为空的时候,要睡眠一会儿。
要命的问题就出在这个睡眠上:
1、假设睡眠的时间是10ms,则当队列为空时,所有工作线程都陆续进入睡眠状态;
2、假设工作线程睡眠期间来了请求,则可能队列中的所有请求都会被延迟10ms才能处理到;
3、在整个服务器的运行周期里,队列为空的几率非常大,因此导致工作线程睡眠的几率也非常大。
毫无疑问,用以上的方法写服务器,延迟高,且性能上不去。
为什么不一有数据到队列,就有工作线程立即去处理呢?(且CPU不能因为轮询空跑)
传统的方法当然是semaphone, condition variable,大熊同学还提了一种开源代码中广泛采用的方案:
1. 用socketpair()系统调用产生两个fd,一个read_fd,一个write_fd
2. 生产者线程写数据到队列后,往write_fd中写入一个字节
3. 工作线程使用read_fd,然后使用epoll_wait等待read_fd上的事件
4. 当epoll_wait返回的时候,工作线程从队列中就能立即取到请求了
5. 工作线程最后还得从read_fd中读出一个字节
以上方案有什么好处呢?
1、队列的检查,不再是基于轮询-睡眠模式,而是基于事件的模式,有数据马上处理,延迟最小;
2、当多个工作线程存在的时候,每个线程都有监听自己的read_fd,所以可以实现按权重等各种复杂的调度算法;
缺点也还是有的:
1、每个工作线程创建的时候,都得调用socketpair()
2、每个线程要占用两个文件句柄
如果可以,后续希望可以测试一下:轮询-睡眠,socketpair()+epoll_wait(),semaphone,condition variable四种方式的性能的优劣。
http://hi.baidu.com/ah__fu/item/587e86d62f35cccb1b72b46e
多线程模型的网络服务器中,一般有专门的网络IO线程,将请求放到请求队列中,此为生产者。然后多个工作线程从队列中获取其中一个请求,进行处理,此是消费者。
通常,通讯使用的队列为锁无关队列。且,为了避免CPU耗慢,当工作线程发现队列为空的时候,要睡眠一会儿。
要命的问题就出在这个睡眠上:
1、假设睡眠的时间是10ms,则当队列为空时,所有工作线程都陆续进入睡眠状态;
2、假设工作线程睡眠期间来了请求,则可能队列中的所有请求都会被延迟10ms才能处理到;
3、在整个服务器的运行周期里,队列为空的几率非常大,因此导致工作线程睡眠的几率也非常大。
毫无疑问,用以上的方法写服务器,延迟高,且性能上不去。
为什么不一有数据到队列,就有工作线程立即去处理呢?(且CPU不能因为轮询空跑)
传统的方法当然是semaphone, condition variable,大熊同学还提了一种开源代码中广泛采用的方案:
1. 用socketpair()系统调用产生两个fd,一个read_fd,一个write_fd
2. 生产者线程写数据到队列后,往write_fd中写入一个字节
3. 工作线程使用read_fd,然后使用epoll_wait等待read_fd上的事件
4. 当epoll_wait返回的时候,工作线程从队列中就能立即取到请求了
5. 工作线程最后还得从read_fd中读出一个字节
以上方案有什么好处呢?
1、队列的检查,不再是基于轮询-睡眠模式,而是基于事件的模式,有数据马上处理,延迟最小;
2、当多个工作线程存在的时候,每个线程都有监听自己的read_fd,所以可以实现按权重等各种复杂的调度算法;
缺点也还是有的:
1、每个工作线程创建的时候,都得调用socketpair()
2、每个线程要占用两个文件句柄
如果可以,后续希望可以测试一下:轮询-睡眠,socketpair()+epoll_wait(),semaphone,condition variable四种方式的性能的优劣。
http://hi.baidu.com/ah__fu/item/587e86d62f35cccb1b72b46e
相关文章推荐
- 多线程+阻塞队列实现生产者-消费者模型获取队列数据问题
- 生产者/消费者模式(阻塞队列) 一个经典的并发模型
- 多进程 队列 实现生产者消费者模型 python 笔记
- 生产者/消费者模型改进版 ——队列
- linux c语言实现队列及用于生产者消费者模型
- 【Java并发】阻塞队列BlockingQueue和生产者-消费者模型笔记
- 生产者与消费者模型(基于单链表、环形队列、多线程、多消费多生产)
- C# 多线程编程 经典模型 生产者和消费者问题
- 生产者/消费者模式(阻塞队列) 一个经典的并发模型
- python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)
- wait,notify,非阻塞队列实现生产者,消费者模型
- 生产者消费者模型与双缓冲队列
- 基于环形队列的生产者消费者模型编写。
- 11.python并发入门(part8 基于线程队列实现生产者消费者模型)
- 基于单链表和基于环形队列的生产者消费者模型
- 利用阻塞队列实现生产者、消费者模型的实例
- 单生产者-多消费者模型中遇到的问题
- 用消息队列模拟生产者消费者模型
- 单生产者-多消费者模型中遇到的问题
- 什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型?