本发明涉及计算机多线程,原子操作,读写锁。具体来说,在多线程环境下,利用原子操作,实现高效的读写锁方法。
背景技术:
在多线程环境下,有这样一种场景(即一种单读、单写的场景),对于一段共享数据队列,只有一个用户做写操作,同时也只有一个用户做读操作的情况下,如何提高线程读写锁效率;常用的方法是利用操作系统提供的线程锁,如图1所示,这种方式功能强大,适应性高,但在此场景效率低,因为线程锁采用的是阻塞的方式,另外,线程锁调用本身也有开销,如果大量的调用加锁/解锁的话,开销也比较大。
技术实现要素:
针对现有技术中存在的技术问题,本发明的目的是提供一种高效读写锁的实现方法,本发明通过一种无需加锁的方法,来实现2个线程(一个读线程和一个写线程)对一个共享数据队列的访问。
为了实现上述目的,本发明的解决方案是:
一种高效读写锁的实现方法,其步骤为:
1)程序的主线程初始化共享数据队列,为该共享数据队列设置一写线程和一读线程,以及设置一整数变量M来保存该共享数据队列最大长度,设置一变量K保存当前该共享数据队列中的数据个数;
2)当该程序需要对该共享数据队列进行写操作时,该主线程调用该共享数据队列的写线程,该写线程做写操作前,先检查K,如果K<M,则把要写的数据插入到该共享数据队列的写端,并且增加K的计数值;
3)当该程序需要对该共享数据队列进行读操作时,该主线程调用该共享数据队列的读线程,该读线程做读操作前,检查K,如果K>0,则从该共享数据队列的读端读取一个元素,并且减少K的计数值。
进一步的,所述步骤2)中,如果K大于或等于M,即该共享数据队列已满,则丢弃当前要写的数据。
进一步的,所述步骤2)中,如果K大于或等于M,即该共享数据队列已满,则等待该共享数据队列未满时,将当前要写的数据插入到该共享数据队列的写端,并且增加K的计数值。
进一步的,所述步骤3)中,如果K=0,即该共享数据队列为空,则采取等待或者轮询的方式检测该共享数据队列中是否存在数据,如果存在,则从该共享数据队列的读端读取一个元素,并且减少K的计数值。
进一步的,该共享数据队列中的元素为写入数据的指针。
本发明的主要内容包括:
a.程序的主线程初始化共享数据队列,用一个整数变量M来保存该共享数据队列最大长度,K保存当前该共享数据队列中的数据个数。
b.当程序需要对该共享数据队列进行写操作时,主线程调用该共享数据队列的写线程,该写线程做写操作前,先检查K,如果K<M,运行push操作,即把要写的数据插入到该共享数据队列的写端,并且K++,如果K>=M,说明该共享数据队列已满,那么可以采取丢弃或者等待的方式。
c.当程序需要对该共享数据队列进行读操作时,主线程调用该共享数据队列的读线程,该读线程做读操作前,检查K,如果K>0,执行pop操作,即从该共享数据队列的读端读取一个元素,K--,如果K=0,说明该共享数据队列为空,那么可以采取等待或者轮询的方式。
与现有技术相比,本发明的优点和积极效果为:
在本发明中,在单读单写的情况下,通过整数加减操作,对共享数据队列中的元素进行访问。相对于采用线程锁,本发明大大提高了读写效率,消除了由于频繁的调用线程锁而产生的开销。
附图说明
图1为传统读写锁的流程图;
图2为本发明方法的流程图。
具体实现方式
本发明流程如图2所示,具体如下:
(1)程序启动后,由该程序的主线程来初始化共享数据队列并创建读线程和写线程,该共享数据队列中的元素为写入数据的指针,共享数据队列最大长度为M,共享数据队列当前元素个数为K,K=0。
(2)当程序需要对该共享数据队列进行写操作时,主线程调用该共享数据队列的写线程,该写线程操作的时候,检查K,如果K<M,写线程执行队列的push操作,即把要写的数据插入到共享数据队列的写端,并执行K++;如果K>=M,返回NULL,表示共享数据队列已经满了,本次写入失败,可以根据自身需要进行等待或者轮询。
(3)当程序需要对该共享数据队列进行读操作时,主线程调用该共享数据队列的读线程,该读线程操作的时候,检查K,如果K>0,读线程执行队列的pop操作,即从共享数据队列的读端读取一个元素,并执行K--;如果K<=0,返回NULL,表示共享数据队列已经空了,即当前无数据可读,可以根据自身需要进行等待或者轮询。
实施例
假如共享数据队列的初始最大长度为M=10,共享数据队列当前的元素个数K=0
例1:写入
检查K=0<M=10,所以可以执行写入,并且执行K++,此时K=1
例2:读取
检查K=1>0,执行读取操作,并且执行K--,此时K=0。