共享队列和双队列

来源:互联网 发布:阿里云服务器上传代码 编辑:程序博客网 时间:2024/05/02 01:48

1第一种方式,共享队列

两个线程共享一个队列,一个往里写,一个往外读,我将写入数据的那个线程叫做writer,读出数据的那个线程叫做reader。这样,writer线程在工作时,reader线程只能等待,reader线程在工作时写线程只能等待。有人会说,可以多来几个reader这样可以使用RWLOCK,但根据应用场景,这里就只有一个消费者。这是一种最简单的方式,也是最基本的方式,效率也很低。在这里就不再讨论这个方式的实现了。

2第二种方式,双队列

两个线程各自一个队列,writer线程往队列1写数据,reader线程从队列2读数据,而在队列2为空时,我将队列1中的数据拼接或交换到队列2中,这样只有这个短暂的交换或拼接动作需要加锁。

那么这里还有个问题,当队列1中有多少数据后拼接到队列2的效率是最高的呢?架构师给了一个建议,先以16个、32个、64个这样的步进进行测试,直到找到性能最好的队列拼接长度。而我最后没有使用架构师给出的这个建议,而是模拟内核与用于空间之间的网络读写接口,这样就把这个任务给了系统调度,大概策略如下:

1、  如果reader线程发现队列2和队列1中都没有数据,则陷入内核睡眠状态,等待event唤醒。

2、  Writer线程当往队列1中写数据时,发现队列1和队列2都没有数据,则认为reader线程肯定会等待在event上,则向reader线程出发event。由于操作系统规则,event类似于condition variable,不会马上被唤醒。所以writer有机会往队列1中继续写入一些数据,其实在多核CPU情况下,writer一直可以往队列1中写数据,除非队列1reader线程锁住。

3、  Reader线程被event唤醒之后,会干以下事情

a)         如果队列2是空的,那么就锁住队列1和队列2,然后将队列1中的数据一次性拼接到队列2中。

b)        Reader线程开始读取队列2中的数据,这里需要注意的是如果是多核CPU,这时writer线程可能正在往队列1中写数据,这与reader线程处理是完全并行的,互不相干,所以双队列在多核CPU上效率很高。

c)         如果reader线程将队列2读空之后,发现writer线程已经又向队列1中写入了一些数据,那么从步骤a)开始重复执行。

d)        如果reader线程将队列2读空之后,发现队列1也是空的,那么说明没有数据了,这时reader线程又回到event上睡眠,等待writer线程的event通知。

原创粉丝点击