一种基于正副本切换的多线程数据无锁读写方法与流程

文档序号:17720142发布日期:2019-05-22 02:06阅读:360来源:国知局
本发明一种基于正副本切换的多线程数据无锁读写方法涉及计算机
技术领域
:,特别是一种多线程数据无锁读写的方法。
背景技术
::为了提高系统/程序的并发处理效率,人们往往会采用多线程的方法。相比于单线程的处理程序,多线程处理程序能够将程序中相互独立的不同事件交给不同的线程进行处理,多个事件并发执行,节省了时间开销,极大地提高程序的性能。但多线程不可避免的会存在竞争关系,例如多个线程需要对同一内存块进行读写访问。如果不能对竞争同一内存块的多线程进行有效控制,内存数据被多个线程毫无规则的进行修改,则会造成内存块中数据异常,乃至一些不可预知的错误。针对多线程的资源竞争问题,一般采取线程锁的办法。使用线程锁,能够有效地控制同一时间段内对内存进行读写的线程。当某个线程对内存资源进行操作时,对该资源上锁,表示已经被占用。防止其他线程此时对内存进行修改。线程锁能够有效合理的控制多线程的资源竞争,使程序能够符合预期的执行任务。但是线程锁的上锁和解锁会造成一部分时间开销,并且随着竞争资源的线程数量、对竞争资源的访问频率增加时,上锁的频率,次数也会线性上涨。这样线程锁本身的时间开销会越来越大。技术实现要素:本发明的目的是针对上述不足之处提供一种基于正副本切换的多线程数据无锁读写方法,能够解决对内存的竞争问题,通过无锁的方法读写某一块内存数据,在保证程序的正确性的同时,利用多线程的特性提高程序的性能;因为该方法是无锁的,所以不会因为线程数量、访问频率的增加而增加额外的时间开销。本发明是采取以下技术方案实现的:一种基于正副本切换的多线程数据无锁读写系统,包括内存数据正本模块、内存数据副本模块、内存数据副本保留模块、写操作和正副本切换模块、以及工作模块。内存数据正本模块,又称待读写内存数据的正本指针模块,简称正本指针,用于在该模块内进行待读写内存数据所有的增加、删除和修改的操作。内存数据副本模块,又称内存数据的副本指针模块,简称副本指针,用于在该模块内进行内存数据的所有读取操作。内存数据副本保留模块,又称内存数据副本的保留指针模块,简称保留指针,用于临时存放当前副本的指针,并保留一个正副本切换周期。写操作和正副本切换模块包括写操作子模块和正副本切换子模块,写操作子模块用于负责在内存数据正本模块中按上述方法进行数据的增加、修改或删除操作;正副本切换子模块用于负责每隔一个周期将正本、副本和保留的数据进行更新同步。工作模块即一般的工作线程,负责从内存数据副本模块中取出数据进行具体的业务逻辑功能实现。一种基于正副本切换的多线程数据无锁读写方法,包括如下步骤,1)在程序初始化阶段,先一次性将现有数据写入内存数据正本模块,并拷贝一份至内存数据副本模块;2)后续建立进行读操作、写操作和正副本切换操作的工作线程;其中写操作和正副本切换操作安排在相同且唯一的工作线程当中,循环执行;写操作和正副本切换操作,这两个操作按先后顺序执行,保证写操作和正副本切换操作无需加锁;读操作则安排在多个工作线程中循环执行,由于读操作实际是指针赋值,属于原子操作,无须进行加锁;3)在写操作和正副本切换操作的工作线程中,规定一个正副本切换周期和一个写操作周期,其中切换操作周期的时长大于写操作周期;在一个切换操作周期内,每隔一个写操作周期进行一次正本数据更新操作;当一个切换操作周期过完后,进行一次正副本切换操作,更新内存数据副本模块和内存数据副本保留模块。所述步骤3)中所述的正副本切换流程,包括如下步骤:3-1)清空保留指针;判断保留指针是否为空,如果是则跳过,否则将保留指针的内存空间都释放掉;3-2)更新接管保留指针;将副本指针的值赋给保留指针,保留至下一次正、副本切换;3-3)生成新的副本指针;先将正本指针的内存空间拷贝一份至临时指针,然后将临时指针赋给副本指针。步骤3-2)中的指针赋值是原子操作,能够确保此次操作前后期间的读操作不会异常。步骤3-3)中的指针赋值是原子操作,能够保证此次操作前后期间的读操作读取到的数据是新副本或老副本其中之一,不会读取到异常数据。发明优点:本发明通过正副本切换的方法,将读操作和写操作的目标分离开来,不会出现多线程资源竞争的情况,无需使用线程锁编程,从而避免了使用锁带来的cpu性能的浪费和各种难以发现或调试的问题,提高了读取数据的准确性和高效性。同时提供了延时功能,在一个正副本切换周期内可以对正本指针进行若干次新增、更新以及撤销删除等操作,只有切换周期过完之后才进行副本更新,增加数据的可操作性。附图说明以下将结合附图对本发明作进一步说明:图1是本发明方法的流程图和各模块的原理框图。具体实施方式下面将结合附图,对本发明的具体实现细节做详细说明。需要注意的是,本发明适用于,但是不局限于下文所描述的数据结构、模块组成等,只要符合本发明思想的应用场景都能适用。本发明方法主要涉及的功能模块有内存数据正本模块、内存数据副本模块、内存数据副本保留模块、写操作和正副本切换模块,以及若干工作模块。本实施例中正、副本的数据结构为一个哈希表模板类hashtableonedime,相当于一个以哈希值为下标的数组,其伪代码如下:template<typenamesttype>classhashtableonedime{public:各种成员方法…dataslot<sttype>*_pslot;};其中类型dataslot是一个槽模板类,成员_pslot用来存放数据,一个哈希值对应一个槽位,相同哈希值存放在同一个槽位中。dataslot的伪代码如下:template<typenamesttype>classdataslot{public:各种成员方法…dlist<sttype>stdata;};dataslot模板类中的stdata成员的类型是一个模板链表类,用来存放实际数据的链表指针。当需要写数据时,根据数据特征值,利用散列算法(例如本例中取数据的ip作为特征值,将ip值与哈希表长度进行取模运算)算出哈希值,找到hashtableonedime类中_pslot成员的对应槽位,按顺序将该数据的节点指针挂载至stdata链表成员的尾节点后面;当需要读取、修改或删除数据时,同样先根据特征值算出哈希值,定位到_pslot的对应槽位上,然后遍历槽位中链表成员的所有数据节点,取出特征值相同的节点即为所需操作的数据,对其进行修改、删除等操作即可。写操作和正副本切换工作模块被安排在唯一的一个工作线程内,写操作模块负责在正本中按上述方法进行数据的增加、修改或删除操作;正副本切换模块负责每隔一个周期将正本、副本和保留的数据进行更新同步,实现方法在技术方案中已做说明。工作模块即一般的工作线程,负责从副本中取出数据进行具体的业务逻辑功能实现。因为取数据的操作实际上为指针赋值,属于原子操作,所以不用担心资源竞争的问题。工作模块的具体实现内容与本发明关联不大,在此便不做赘述。本发明中读写操作分开的意义在于:根据实际应用场景的不同,待读写的内存数据结构可能比较复杂,对其进行写操作不是原子操作。而读写操作同时进行的话则必须加锁,否则难免会导致不可预知的问题。而加锁的话就会存在
背景技术
:中存在的cpu性能浪费和效率降低的问题。本发明中保留副本指针的意义在于:如果不保留副本指针,直接释放其内存空间,然后再拷贝一份正本指针的内存空间至副本指针,那么为了防止在释放和重新拷贝两个操作之间进行读操作又必须加锁,因此又会导致上述的弊端。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1