对象更新、读取方法及装置

文档序号:1963591 发布日期:2021-12-14 浏览:15次 >En<

阅读说明:本技术 对象更新、读取方法及装置 (Object updating and reading method and device ) 是由 洪春涛 于 2021-11-17 设计创作,主要内容包括:本说明书实施例提供一种对象更新、读取方法及装置,在对象更新方法中,任意的第一CPU核的第一线程请求获取写锁,该写锁用于表示对第一对象执行更新的权限。读取第一指针,该第一指针指向第一对象。根据第一指针,读取第一对象并复制,得到第二对象。对第二对象的内容进行调整,得到调整后的第二对象。修改第一指针,以使其指向调整后的第二对象。释放写锁。(In the object updating method, a first thread of an arbitrary first CPU core requests to acquire a write lock, and the write lock is used for expressing the authority of executing updating on a first object. A first pointer is read, the first pointer pointing to a first object. And reading and copying the first object according to the first pointer to obtain a second object. And adjusting the content of the second object to obtain the adjusted second object. The first pointer is modified to point to the adjusted second object. The write lock is released.)

对象更新、读取方法及装置

技术领域

本说明书一个或多个实施例涉及计算机技术领域,尤其涉及一种对象更新、读取方法及装置。

背景技术

多核处理系统能够在单位时间内处理更多的任务,处理能力更强,应用也越发广泛。在利用多核处理系统运行多线程任务时,该多个线程之间可以具有都能够操作的共享对象。并且,在更新所述的共享对象时,同一时刻只能有一个线程更新,以避免线程冲突导致数据错误。当前技术中,各个线程之间可以申请锁(Lock),成功获取到锁的线程可以操作该共享对象,未获取到锁的线程只能等待。需要说明,这里的锁通常为全局变量,从而线程申请锁的过程中通常需要进行跨CPU核通信。

发明内容

本说明书一个或多个实施例描述了一种对象更新、读取方法及装置,可以确保针对原对象的读取操作的安全性。

第一方面,提供了一种对象更新方法,包括:

任意的第一CPU核的第一线程请求获取写锁;所述写锁用于表示对所述第一对象执行更新的权限;

读取第一指针,所述第一指针指向所述第一对象;

根据所述第一指针,读取所述第一对象并复制,得到第二对象;

对所述第二对象的内容进行调整,得到调整后的第二对象;

修改所述第一指针,以使其指向所述调整后的第二对象;

释放所述写锁。

第二方面,提供了一种对象读取方法,包括:

任意的第一CPU核的第一线程读取第一指针,所述第一指针指向所述第一对象;所述第一对象具有对应的第一标志位数组,其中的每个标志位对应于一个线程;

根据所述第一指针,读取所述第一标志位数组中对应于所述第一线程的第一标志位;

将所述第一标志位的取值修改为预定值;所述预定值指示所述第一线程正在访问所述第一对象;

读取所述第一对象;

在读取所述第一对象后,将所述第一标志位的取值恢复为初始值。

第三方面,提供了一种对象更新装置,包括:

获取单元,用于请求获取写锁;所述写锁用于表示对所述第一对象执行更新的权限;

读取单元,用于读取第一指针,所述第一指针指向所述第一对象;

复制单元,用于根据所述第一指针,读取所述第一对象并复制,得到第二对象;

调整单元,用于对所述第二对象的内容进行调整,得到调整后的第二对象;

修改单元,用于修改所述第一指针,以使其指向所述调整后的第二对象;

释放单元,用于释放所述写锁。

第四方面,提供了一种对象读取装置,包括:

读取单元,用于读取第一指针,所述第一指针指向所述第一对象;所述第一对象具有对应的第一标志位数组,其中的每个标志位对应于一个线程;

所述读取单元,还用于根据所述第一指针,读取所述第一标志位数组中对应于所述第一线程的第一标志位;

修改单元,用于将所述第一标志位的取值修改为预定值;所述预定值指示所述第一线程正在访问所述第一对象;

所述读取单元,还用于读取所述第一对象;

恢复单元,用于在读取所述第一对象后,将所述第一标志位的取值恢复为初始值。

第五方面,提供了一种计算机存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行第一方面或第二方面的方法。

第六方面,提供了一种计算设备,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现第一方面或第二方面的方法。

本说明书一个或多个实施例提供的对象更新、读取方法及装置,在任意的第一线程更新多线程共享的对象时,其不直接更新原对象,而是针对原对象的副本进行更新。之后,将指向原对象的指针修改为指向更新后的对象副本。由此可以确保针对原对象的读取操作的安全性。此外,由于不会针对原对象执行更新操作,从而针对原对象的读操作不需要加锁,由此可以降低通信代价,节约计算机资源。

附图说明

为了更清楚地说明本说明书实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本说明书的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。

图1示出根据一个实施例的多核处理系统示意图;

图2示出根据一个实施例的对象更新方法流程图;

图3a示出第一内存区域示意图之一;

图3b示出第二内存区域示意图之二;

图4示出根据一个实施例的对象读取方法流程图;

图5示出根据一个实施例的对象更新装置示意图;

图6示出根据一个实施例的对象读取装置示意图。

具体实施方式

下面结合附图,对本说明书提供的方案进行描述。

图1示出根据一个实施例的多核处理系统示意图。图1中,多核处理系统包括多个CPU,分别表示为:CPU1、CPU2、…。每个CPU可以包括若干CPU核,比如,CPU1可以包括CPU核1和CPU核2,CPU2可以包括CPU核3和CPU核4。每个CPU核可以绑定若干线程,在本说明书的以下描述中,将以一个CPU核绑定一个线程为例来进行说明。比如,CPU核1可以绑定线程A,CPU核2可以绑定线程B,CPU核3可以绑定线程C以及CPU核4可以绑定线程D。且各线程可以分配有不同的tid。

图1中,每个CPU核还可以具有对应的本地缓存(Cache),Cache是CPU与内存之间的缓存层,以减少对内存的访问频率。比如,CPU核1在从内存中读取数据时,其先将数据读取到Cache1中,然后再从Cache1中读取该数据。需要说明,CPU从内存中读取数据到Cache的时候,并不是一个字节一个字节读取,而是一块一块的方式来读取数据的,这一块一块的数据被称为CPU Line(缓存行),所以CPU Line是CPU从内存读取数据到Cache的单位。

需要说明,在多核处理系统中,不同CPU核的线程可以并发执行。

多个线程并发执行时,往往需要访问同一数据。从被访问的数据看,该数据共享给不同线程。在多个线程访问该共享数据时,需要保证该共享数据的完整性。例如,不能两个线程同时修改共享数据;一个线程不能读到修改了一半的共享数据。经典的方式是使用锁机制。例如,在线程对数据进行读操作的过程中为该数据加上读锁。在读操作之后,再释放读锁。类似的,在线程对数据进行写操作的过程中为该数据加上写锁。在写操作之后,再释放写锁。通常用read_ref作为读操作线程的引用计数,用writer_ID表示写操作线程的ID。

对于不同线程对同一数据执行的都是读操作来说,可以加多次读锁。例如,CPU核1的线程A对某一数据要执行读操作,则在执行读操作之前,对该数据加读锁,具体是将read_ref的值加1(例如read_ref的数据类型为整形,且初始值为0),之后对该数据进行读取。在读取的过程中,CPU核2的线程B也要对同一数据执行读操作,则将read_ref的值加1,并对该数据进行读取。应理解,此时read_ref的值为2。线程A的读操作执行完毕之后,将read_ref的值减1,并释放读锁。此时,read_ref的值为1。之后,线程B对该数据的读操作执行完毕,将read_ref的值减1,并释放读锁。此时,read_ref的值为0。对同一数据的读锁可以重复加,因此,读锁之间具有共享性。

对于不同线程对同一数据执行的都是写操作来说,只能加一次写锁。例如,线程A对某一数据要执行写操作,则在执行写操作之前,对该数据加写锁,具体是将writer_ID的值更新为线程A的ID(例如writer_ID的数据类型为整形,且初始值为0;任一线程的ID不为0),之后对该数据进行写操作。在写的过程中,线程B也要对同一数据执行写操作,但因writer_ID的值此时不为0,因此线程B不能加写锁,也不能对该数据进行写操作。线程A的写操作执行完毕之后,释放写锁,即将writer_ID的值更新为0。线程B在前次加写锁失败并等待一段时间后,得知writer_ID的值此时为0,可以加写锁。之后,writer_ID的值更新为线程B的ID,之后对该数据进行写操作。线程B的写操作执行完毕之后,释放写锁,即将writer_ID的值更新为0。可见,对同一数据的写锁不可以重复加,因此,写锁之间具有互斥性。

此外,写锁和读锁也是互斥的,即在任一时刻,对同一数据加了读锁就不能再加写锁,加了写锁也不能加读锁。这样,某一线程在对一数据进行读操作前,需要检查该数据的writer_ID值是否为0。如果为0,才可以进行读操作;如果不为0,需要等待writer_ID值变为0。类似的,某一线程在对一数据进行写操作前,需要检查该数据的read_ref值是否为0。如果为0,才可以进行写操作;如果不为0,需要等待read_ref值变为0。实际上,对于加读锁,更多情况下,为了进一步避免在检查writer_ID值的操作与相应的读操作之间另一线程同时为写操作而进行的加写锁操作,即为了避免该种情况下导致的冲突检测失效,将read_ref的值加1之后,还将再次检查此时的writer_ID值是否为0。如果为0,才执行读操作。类似的,对于加写锁,更多情况下,为了进一步避免在检查read_ref值的操作与相应的写操作之间有另一线程同时为读操作而进行的加读锁操作,即为了避免该种情况下导致的冲突检测失效,将writer_ID值更新为写线程的ID之后,还将再次检查此时该read_ref值是否为0。如果为0,才执行写操作。

上述线程对read_ref值、writer_ID值的更改,属于原子操作。原子操作一般是CPU提供的指令,具有不可分割性。一个线程在执行一个原子操作时,不会被别的线程打断,不会切换到其它线程。换句话说,这种原子操作一旦开始,就一直运行到该操作结束。

以上就是传统的保证多线程的共享数据完整性的方法。本申请的发明人经研究,发现上述方法存在以下问题:首先,数据的读写操作只能二选一,这将极大地降低读写效率。此外,在不同CPU核的线程在一段时间内对同一数据执行大量读操作,而没有写操作的情况下,每个CPU核对应的本地缓存中都会维护一个read_ref值。并且按照现有技术中的实现方式,每个CPU核对应的本地缓存中的read_ref值需要保持一致。这样,对于多核处理系统来说,一个CPU核对应的本地缓存中的read_ref值一旦发生变化,要与其它CPU核通信以通知这一改变。其它CPU核收到通知后更新各自本地缓存中的read_ref值。也就是说,这种情况下,需要多次跨CPU核通信,这将极大地耗费通信资源。

为此,本说明书将提供一种对象更新、读取方法。在对象更新方法中,不直接更新原对象,而是针对原对象的副本进行更新。之后,将指向原对象的指针修改为指向更新后的对象副本。由此可以确保针对原对象的读取操作的安全性。此外,由于不会针对原对象执行更新操作,从而针对原对象的读操作不需要加锁,由此可以降低通信代价,节约计算机资源。

在对象读取方法中,在针对某对象开始执行读操作之前,从该对象对应的标志位数组中读取对应于当前线程的标志位,之后只针对该标志位进行修改,以实现该对象的引用计数。也就是说,在读取对象的过程中,各线程只修改各自对应的标志位,不需要加锁,从而不需要进行跨CPU核通信,由此,可以提升对象读取效率。

以下针对本方案进行详细说明。

图2示出根据一个实施例的对象更新方法流程图。可以理解,该方法可以通过任何具有计算、处理能力的装置、设备、平台、设备集群来执行。比如,图1中的多核处理系统。如图2所示,该方法至少包括以下步骤。

步骤202,任意的第一CPU核的第一线程请求获取写锁,该写锁用于表示对第一对象执行更新的权限。

上述第一对象(也称数据对象,表示为obj1)例如可以为数据表、记事本或者word文档等。该第一对象还可以具有第一标志位数组,表示为:flags1[],其中的每个标志位对应于一个线程(该对应关系的建立后续说明),且具有对应的初始值(比如,0)。该初始值在对应线程开始访问第一对象时被修改(比如,修改为1),且在结束访问时被恢复。需要说明,每个标志位的取值长度可以为一个缓存行,比如,可以为64个字节。由此可以确保某一线程针对对应标志位的修改,不会造成其它线程的本地缓存结果失效。此外,每个标志位还具有对应的位置索引,各标志位的位置索引可以分别为:0,1,2,…,n-1,其中,n为标志位的数目。举例来说,假设上述第一标志位数组中标志位的数目可以为256个,那么每个标志位的位置索引分别为:0,1,2,…,255。

在本说明书实施例中,基于上述第一对象以及第一标志位数组,还可以执行实例化预定义类的步骤,该预定义类可以包括两个变量。具体地,在实例化过程中,可以将obj1作为一个类参数,赋值给第一变量,以及将flags1[]作为另一个类参数,赋值给第二变量。上述实例化的结果(也称类对象)可以表示为:RefCountedObj1。

通过实例化预定义类,可以实现从内存中申请第一内存区域,并将第一对象和对应的第一标志位数组按照先后顺序,连续存放在第一内存区域中。

图3a和图3b示出第一内存区域示意图。图3a中,第一对象在前,第一标志位数组在后。应理解,在该种情况下,第一内存区域的地址即为第一对象在第一内存区域的位置。图3b中,第一标志位数组在前,第一对象在后。应理解,在该种情况下,第一对象在第一内存区域的位置需根据第一内存区域的地址和第一标志位数组的大小确定。

回到图2中,上述第一CPU核例如可以为图1中CPU核1、CPU核2、CPU核3以及CPU核4中任意一CPU核。该第一CPU核可以与多个线程绑定,在本说明书的以下描述中,将以第一CPU核与一个线程绑定为例进行说明。

本说明书中,针对与每个CPU核绑定的各线程,可以为其分配相应的tid。各线程的tid可以与标志位的位置索引相一致,也即各线程的tid可以为从0开始的整数值,由此可以建立线程与标志位之间的对应关系,也即可以实现将每个标志位分配给一个线程。举例来说,假设有256个线程,那么该256个线程的tid可以分别为:0,1,2,…,255。

此外,上述写锁与对象之间是一一对应的关系,即针对每个对象都设置对应的写锁。从而,上述请求获取写锁是指请求获取对应于第一对象的写锁,其获取过程与现有技术相同。即判断writer_ID的值是否为初始值,如果否,则请求失败;如果是,则请求成功,之后将writer_ID的值修改为第一线程的tid,至此就完成了针对第一对象的写锁的获取。

需要说明,在本说明书实施例中,writer_ID的初始值可以设为除0~255之外的任一整数值。

步骤204,第一线程读取第一指针,该第一指针指向第一对象。

这里的第一指针(表示为ptr)可以是维护在内存中的。需要说明,针对该第一指针的读取属于原子操作,从而不需要锁。关于原子操作的解释可以参见上文所述。

在第一线程第一次读取第一指针时,通常会先判断其它CPU核的本地缓存中是否已存储有第一指针,若是,则从其它CPU核的本地缓存中读取第一指针,否则,从内存中读取第一指针。应理解,在第一次读取之后,当第一线程再次读取第一指针时,其可以直接从第一CPU核的本地缓存中读取该第一指针。

需要说明,上述第一指针指向第一对象可以理解为,第一指针的值为第一对象的第一地址。

应理解,当还执行上述实例化预定义类的步骤时,上述第一指针的值可以指向RefCountedObj1,也即第一指针的值为第一内存区域的地址(一般为首地址)。

此外,第一线程还可以记录第一指针的值,即记录第一对象的第一地址或者第一内存区域的地址。

步骤206,第一线程根据第一指针,读取第一对象并复制,得到第二对象。

具体地,优先从第一CPU核的本地缓存中读取第一对象,若读取到,则结束;否则,从其它CPU核的本地缓存中读取该第一对象,若读取到,则结束,否则从内存中读取第一对象。

以第一指针的值为第一内存区域的地址为例来说,从内存中读取第一对象的过程可以为:若在该第一内存区域中,第一对象在前,第一标志位数组在后,那么直接可以根据第一内存区域的地址,读取第一对象。否则,若在该内存区域中,第一标志位数组在前,第一对象在后,那么可以根据第一内存区域的地址和第一标志位数组的大小,读取第一对象。比如,可以通过如下公式来确定第一对象在第一内存区域的位置:ptr+256*64,其中,ptr为第一内存区域的地址(一般为首地址),256为标志位的数目,64为标志位的大小(即标志位的取值长度),256*64即为第一标志位数组的大小。

上述通过复制得到的第二对象可以表示为:obj2。

步骤208,第一线程对第二对象的内容进行调整,得到调整后的第二对象。

以第一对象和第二对象为数据表为例来说,可以通过修改数据表中的字段值,得到调整后的第二对象,表示为obj2。

针对调整后的第二对象,还可以为其设置相应的第二标志位数组,表示为flags2[]。应理解,该第二标志位数组中的每个标志位也具有对应的位置索引,分别为:0,1,2,…,n-1,其中,n为标志位的数目。也即第二标志位数组中各标志位的位置索引与各线程的tid相一致,由此可以建立第二标志位数组中每个标志位与线程的对应关系,也即可以实现将其中的每个标志位分配给一个线程。

对于上述第二标志位数组,可以初始化每个标志位的取值,比如,可以初始化为0。在一个示例中,每个标志位的取值长度可以为一个缓存行,比如,可以为64个字节。由此可以确保某一线程针对对应标志位的修改,不会造成其它线程的本地缓存结果失效。

需要说明,上述第二标志位数组中每个标志位的初始值在对应线程开始访问调整后的第二对象时被修改(比如,修改为1),且在结束访问时被恢复。

可选地,在获取到调整后的第二对象后,可以再次实例化预定义类。如上所述,预定义类可以包括两个变量。具体地,在本次实例化过程中,可以将obj2作为一个类参数,赋值给第一变量,以及将flags2[]作为另一个类参数,赋值给第二变量。上述实例化的结果(也称类对象)可以表示为:RefCountedObj2。

通过实例化预定义类,可以实现从内存中申请第二内存区域,并将调整后的第二对象和第二标志位数组按照先后顺序,连续存放在第二内存区域中。

步骤210,第一线程修改第一指针,以使其指向调整后的第二对象。

这里,可以通过原子操作来修改第一指针。也就是说,在本说明书实施例中,针对第一指针的读和写操作均为原子操作,因此在根据该指针读取数据时不会读取到脏数据。

上述修改后的第一指针的值为调整后的第二对象的第二地址。

当还执行上述实例化预定义类的步骤时,修改后的第一指针指向RefCountedObj2,也即修改后的第一指针的值为第二内存区域的地址(一般为首地址)。

应理解,上述修改第一指针的操作是在得到调整后的第二对象后执行的,从而第一指针可以永远指向有效的对象。

步骤212,第一线程释放写锁。

该释放写锁的步骤可以包括:将writer_ID的值恢复为初始值,至此就完成了针对第一对象的更新。

需要说明,在第一线程修改第一指针的值之后,其可以向其它CPU核的其它线程发送指针更新消息,以使其它线程更新其它CPU核的本地缓存中存储的修改前的第一指针。比如,在第一线程为CPU核1的线程A时,那么可以向CPU核2、CPU核3和CPU核4各自对应的线程B、线程C和线程D发送指针更新消息。线程B、线程C和线程D在接收到指针更新消息之后,可以更新对应CPU核的本地缓存中存储的修改前的第一指针。

也就是说,在第一指针的值被修改后,需要一次跨CPU核通信,之后,各线程可以直接从对应CPU核的本地缓存中读取即可。

还需要说明,第一线程还可以将上述记录的第一对象的第一地址或者第一内存区域的地址放入地址回收队列。该地址回收队列用于存放无用对象的地址。

在将第一地址或者第一内存区域的地址放入回收队列之后,回收线程从回收队列中读取第一地址或者第一内存区域的地址,该回收线程为任一负责回收无用对象的线程。若读取失败,则等待;若读取成功,则判断第一地址或者第一内存区域的地址对应的第一对象是否满足删除条件,在第一对象满足删除条件的情况下,删除第一对象或实例化的结果(包括第一对象和第一标志位数组),以释放内存资源。否则,等待一段时间后再次判断是否满足删除条件,直至满足为止。

在一个示例中,上述判断是否满足删除条件可以包括:判断针对第一指针的修改时长是否达到预定时长,如是则满足,否则不满足。

在另一个示例中,判断是否满足删除条件可以包括:遍历第一对象的第一标志位数组中的每个标志位的取值是否均为初始值;其中,第一标志位数组中的每个标志位对应取值为初始值指示对应线程未访问第一对象;若是,则确定第一对象满足删除条件,否则不满足。

综上,本说明书实施例提供的对象更新方法,在任意的第一线程更新多线程共享的对象时,其不直接更新原对象,而是针对原对象的副本进行更新。之后,将指向原对象的指针修改为指向更新后的对象副本。由此可以确保针对原对象的读取操作的安全性,也即可以确保在任何时候都读取不到脏数据。此外,由于不会针对原对象执行更新操作,从而针对原对象的读操作不需要加锁,由此就可以使得各线程之间不需要任何跨CPU核的通信,这可以降低通信代价,节约计算机资源。

图4示出根据一个实施例的对象读取方法流程图。该方法可以通过任何具有计算、处理能力的装置、设备、平台、设备集群来执行。比如,图1中的多核处理系统。如图4所示,该方法至少包括以下步骤。

步骤402,任意的第一CPU核的第一线程读取第一指针。

这里的第一指针指向第一对象,第一对象具有对应的第一标志位数组,其中的每个标志位对应于一个线程。这里的第一指针、第一对象以及第一标志位数组以及标志位的相关描述可以参见上文,本说明书在此不复赘述。

上述针对第一指针的读取属于原子操作,从而不需要锁。关于原子操作的解释可以参见上文所述。

具体地,可以优先从第一CPU核的本地缓存中读取第一对象,若读取到,则结束;否则,从其它CPU核的本地缓存中读取该第一对象,若读取到,则结束,否则从内存中读取第一对象。

此外,如上文所述,第一对象和对应的第一标志位数组可以按照先后顺序,连续存放在第一内存区域中,从而上述第一指针的值可以为第一内存区域的地址。

步骤404,第一线程根据第一指针,读取第一标志位数组中对应于第一线程的第一标志位。

如上所述,本说明书中,针对与每个CPU核绑定的各线程,可以为其分配相应的tid。各线程的tid可以与标志位的位置索引相一致,也即各线程的tid可以为从0开始的整数值,由此可以建立线程与标志位之间的对应关系,也即可以实现将每个标志位分配给一个线程。

以下分两种情况对上述读取第一标志位的过程进行说明。

第一种,在第一内存区域中,第一对象在前,第一标志位数组在后,则读取第一标志位可以包括:根据第一内存区域的地址、第一对象的大小、第一线程的位置索引以及标志位的大小,读取第一标志位。

在一个例子中,可以根据如下公式来确定第一标志位在第一内存区域的位置:ptr+S(obj1)+n*64,其中,ptr为第一内存区域的地址(一般为首地址),S(obj1)为第一对象的大小,64为标志位的大小(即标志位的取值长度),n为第一线程的位置索引,其取值范围为:[0,255]。如上所述,第一线程的tid与其位置索引相一致,从而n也可以理解为是第一线程的唯一标识tid。

第二种,在第一内存区域中,第一标志位数组在前,第一对象在后,则读取第一标志位可以包括:根据第一内存区域的地址、第一线程的位置索引以及标志位的大小,读取第一标志位。

在一个例子中,可以根据如下公式来确定第一标志位在第一内存区域的位置:ptr+n*64,其中,ptr为第一内存区域的地址(一般为首地址),64为标志位的大小(即标志位的取值长度),n为第一线程的位置索引,其取值范围为:[0,255]。

应理解,上述是第一线程第一次读取第一标志位的过程,也即从内存中读取第一标志位的过程。当该第一标志位被读取一次之后,就会存储到第一CPU核的本地缓存中,从而第一线程需要再次读取第一标志位时,只需从本地缓存中读取即可,无需再执行跨CPU核通信。

步骤406,第一线程将第一标志位的取值修改为预定值。

该预定值指示第一线程正在访问第一对象。在一个例子中,该预定值可以为1。

以第一标志位的初始值为0为例来说,上述将第一标志位的取值修改为预定值可以包括:对第一标志位的取值执行加1操作。

步骤408,第一线程读取第一对象。

具体地,优先从第一CPU核的本地缓存中读取第一对象,若读取到,则结束;否则,从其它CPU核的本地缓存中读取该第一对象,若读取到,则结束,否则从内存中读取第一对象。

以第一指针的值为第一内存区域的地址为例来说,从内存中读取第一对象的过程可以为:若在该第一内存区域中,第一对象在前,第一标志位数组在后,那么直接可以根据第一内存区域的地址,读取第一对象。否则,若在该内存区域中,第一标志位数组在前,第一对象在后,那么可以根据第一内存区域的地址以及第一标志位数组的大小,读取第一对象。比如,可以通过如下公式来确定第一对象在第一内存区域的位置:ptr+256*64,其中,ptr为第一内存区域的地址(一般为首地址),256为标志位的数目,64为标志位的大小(即标志位的取值长度),256*64即为第一标志位数组的大小。

步骤410,第一线程在读取第一对象后,将第一标志位的取值恢复为初始值。

还以第一标志位的初始值为0为例来说,上述将第一标志位的取值恢复为初始值可以包括:对第一标志位的取值执行减1操作。

需要说明,本说明书实施例中,针对标志位的修改和恢复只有对应的线程会执行,其它线程不会执行,因此不需要加锁。此外,在各标志位的取值长度为一个缓存行时,各线程针对各自标志位的修改或恢复不会造成其他线程的本地缓存结果失效。

综上,本说明书实施例提供的对象读取方法,针对对象的读取操作为只读操作,不需要加锁,且不会造成跨CPU核通信,由此可以大大节约计算机资源。

与上述对象更新方法对应地,本说明书一个实施例还提供的一种对象更新装置。该装置设置于多核处理系统,该多核处理系统包括多个CPU,每个CPU包括若干CPU核。如图5所示,该装置可以包括:

获取单元502,用于请求获取写锁,该写锁用于表示对第一对象执行更新的权限。

读取单元504,用于读取第一指针,该第一指针指向第一对象。

其中,针对第一指针的读取为原子操作。

读取单元504具体用于:

从第一CPU核的本地缓存中读取第一指针;或,

从第二CPU核的本地缓存中读取第一指针;或,

从内存中读取第一指针。

复制单元506,用于根据第一指针,读取第一对象并复制,得到第二对象。

调整单元508,用于对第二对象的内容进行调整,得到调整后的第二对象。

修改单元510,用于修改第一指针,以使其指向调整后的第二对象。

释放单元512,用于释放写锁。

可选地,该装置还包括:

设置单元514,用于针对调整后的第二对象,设置对应的第二标志位数组。

分配单元516,用于将第二标志位数组中的每个标志位分配给一个线程,并初始化每个标志位的取值。其中,初始化后的每个标志位的取值在对应线程开始访问所述调整后的第二对象时被修改,且在结束访问时被恢复。

可选地,该装置还包括:

申请单元,用于申请第二内存区域。

存储单元,用于将调整后的第二对象以及第二标志位数组按照先后顺序,连续存放在第二内存区域。

修改单元510具体用于:

将第一指针的值修改为第二内存区域的地址。

可选地,该装置还包括:发送单元;

发送单元,用于向其它CPU核的其它线程发送指针更新消息,以使其它线程更新其它CPU核的本地缓存中存储的修改前的第一指针。

可选地,该装置还包括:加入单元518。

获取单元502,还用于根据第一指针,获取第一对象的第一地址。

加入单元518,用于将第一地址加入地址回收队列,该地址回收队列用于存放无用对象的地址。

可选地,该装置还包括:判断单元520和删除单元522。

读取单元504,还用于从回收队列中读取第一地址,该回收线程为任一负责回收无用对象的线程。

判断单元520,用于判断第一地址对应的第一对象是否满足删除条件。

判断单元520具体用于:

遍历第一对象的第一标志位数组中的每个标志位的取值是否均为初始值;其中,第一标志位数组中的每个标志位对应于一个线程,其对应取值为初始值指示对应线程未访问第一对象;

若是,则确定第一对象满足删除条件。

删除单元522,用于在第一对象满足删除条件的情况下,删除第一对象。

本说明书上述实施例装置的各功能模块的功能,可以通过上述方法实施例的各步骤来实现,因此,本说明书一个实施例提供的装置的具体工作过程,在此不复赘述。

本说明书一个实施例提供的对象更新方法,可以确保针对原对象的读取操作的安全性。

与上述对象读取方法对应地,本说明书一个实施例还提供的一种对象读取装置。该装置设置于多核处理系统,该多核处理系统包括多个CPU,每个CPU包括若干CPU核。如图6所示,该装置可以包括:

读取单元602,用于读取第一指针,该第一指针指向第一对象。第一对象具有对应的第一标志位数组,其中的每个标志位对应于一个线程。

其中,第一对象和第一标志位数组按照先后顺序存储在第一内存区域中,第一指针的值为第一内存区域的地址。

读取单元602,还用于根据第一指针,读取第一标志位数组中对应于第一线程的第一标志位。

修改单元604,用于将第一标志位的取值修改为预定值,该预定值指示第一线程正在访问第一对象。

其中,初始值为0,修改单元604具体用于:

对第一标志位的取值执行加1操作。

读取单元602,还用于读取第一对象。

恢复单元606,用于在读取第一对象后,将第一标志位的取值恢复为初始值。

恢复单元606具体用于:

对第一标志位的取值执行减1操作。

其中,在第一内存区域中,第一对象在前,第一标志位数组在后;

读取单元602具体用于:

根据第一内存区域的地址、第一对象的大小、第一线程的位置索引以及标志位的大小,读取第一标志位;

读取单元602还具体用于:

根据第一内存区域的地址,读取第一对象。

其中,在第一内存区域中,第一标志位数组在前,第一对象在后;

读取单元602具体用于:

根据第一内存区域的地址、第一线程的位置索引以及标志位的大小,读取第一标志位;

读取单元602还具体用于:

根据第一内存区域的地址以及第一标志位数组的大小,读取第一对象。

其中,第一线程的位置索引根据第一线程的唯一标识确定。

本说明书上述实施例装置的各功能模块的功能,可以通过上述方法实施例的各步骤来实现,因此,本说明书一个实施例提供的装置的具体工作过程,在此不复赘述。

本说明书一个实施例提供的对象读取方法,可以节约通信资源。

根据另一方面的实施例,还提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行结合图2或图4所描述的方法。

根据再一方面的实施例,还提供一种计算设备,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现结合图2或图4所描述的方法。

本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于设备实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。

结合本说明书公开内容所描述的方法或者算法的步骤可以硬件的方式来实现,也可以是由处理器执行软件指令的方式来实现。软件指令可以由相应的软件模块组成,软件模块可以被存放于RAM存储器、闪存、ROM存储器、EPROM存储器、EEPROM存储器、寄存器、硬盘、移动硬盘、CD-ROM或者本领域熟知的任何其它形式的存储介质中。一种示例性的存储介质耦合至处理器,从而使处理器能够从该存储介质读取信息,且可向该存储介质写入信息。当然,存储介质也可以是处理器的组成部分。处理器和存储介质可以位于ASIC中。另外,该ASIC可以位于服务器中。当然,处理器和存储介质也可以作为分立组件存在于服务器中。

本领域技术人员应该可以意识到,在上述一个或多个示例中,本发明所描述的功能可以用硬件、软件、固件或它们的任意组合来实现。当使用软件实现时,可以将这些功能存储在计算机可读介质中或者作为计算机可读介质上的一个或多个指令或代码进行传输。计算机可读介质包括计算机存储介质和通信介质,其中通信介质包括便于从一个地方向另一个地方传送计算机程序的任何介质。存储介质可以是通用或专用计算机能够存取的任何可用介质。

上述对本说明书特定实施例进行了描述。其它实施例在所附权利要求书的范围内。在一些情况下,在权利要求书中记载的动作或步骤可以按照不同于实施例中的顺序来执行并且仍然可以实现期望的结果。另外,在附图中描绘的过程不一定要求示出的特定顺序或者连续顺序才能实现期望的结果。在某些实施方式中,多任务处理和并行处理也是可以的或者可能是有利的。

以上所述的具体实施方式,对本说明书的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本说明书的具体实施方式而已,并不用于限定本说明书的保护范围,凡在本说明书的技术方案的基础之上,所做的任何修改、等同替换、改进等,均应包括在本说明书的保护范围之内。

22页详细技术资料下载
上一篇:一种医用注射器针头装配设备
下一篇:延迟消息处理方法、装置与系统

网友询问留言

已有0条留言

还没有人留言评论。精彩留言会获得点赞!

精彩留言,会给你点赞!