CN108874446A - 多线程访问方法及装置 - Google Patents
多线程访问方法及装置 Download PDFInfo
- Publication number
- CN108874446A CN108874446A CN201810326813.8A CN201810326813A CN108874446A CN 108874446 A CN108874446 A CN 108874446A CN 201810326813 A CN201810326813 A CN 201810326813A CN 108874446 A CN108874446 A CN 108874446A
- Authority
- CN
- China
- Prior art keywords
- lock
- global
- key
- value pair
- thread
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
- 238000000034 method Methods 0.000 title claims abstract description 63
- 230000004044 response Effects 0.000 claims abstract description 7
- 230000006870 function Effects 0.000 claims description 116
- 238000004590 computer program Methods 0.000 claims description 17
- 238000007599 discharging Methods 0.000 claims description 5
- 238000004364 calculation method Methods 0.000 claims 1
- 230000008569 process Effects 0.000 description 18
- 239000011800 void material Substances 0.000 description 7
- 238000010586 diagram Methods 0.000 description 5
- 230000007246 mechanism Effects 0.000 description 4
- 230000009471 action Effects 0.000 description 3
- 230000008901 benefit Effects 0.000 description 3
- 238000004064 recycling Methods 0.000 description 3
- FGUUSXIOTUKUDN-IBGZPJMESA-N C1(=CC=CC=C1)N1C2=C(NC([C@H](C1)NC=1OC(=NN=1)C1=CC=CC=C1)=O)C=CC=C2 Chemical compound C1(=CC=CC=C1)N1C2=C(NC([C@H](C1)NC=1OC(=NN=1)C1=CC=CC=C1)=O)C=CC=C2 FGUUSXIOTUKUDN-IBGZPJMESA-N 0.000 description 2
- 238000005516 engineering process Methods 0.000 description 2
- 241000406668 Loxodonta cyclotis Species 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 238000013480 data collection Methods 0.000 description 1
- 230000007547 defect Effects 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 238000000926 separation method Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/30—Arrangements for executing machine instructions, e.g. instruction decode
- G06F9/38—Concurrent instruction execution, e.g. pipeline or look ahead
- G06F9/3867—Concurrent instruction execution, e.g. pipeline or look ahead using instruction pipelines
- G06F9/3869—Implementation aspects, e.g. pipeline latches; pipeline synchronisation and clocking
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明提供了一种多线程访问方法及装置,该方法包括:响应于线程对函数对象的访问,调用全局临界区对象对全局键值对表进行加锁;获取线程调用所述全局锁加锁时的键值;判定全局键值对表中是否存在与加锁时的键值对应的锁对象,每一锁对象设置有用于记录引用次数的引用计数器;若全局键值对表中不存在对应的锁对象,创建锁对象,为该锁对象生成引用计数器并将该引用计数器的计数值加1,并将该锁对象以及锁对象与指定的键值之间的对应关系添加到全局键值对表;调用全局临界区对象对全局键值对表进行解锁;调用创建的锁对象为线程访问的函数对象进行加锁。本发明解决了利用类成员锁实现线程访问存在的多线程问题,保证了程序的运行稳定性。
Description
技术领域
本发明涉及多线程访问技术领域,尤其涉及一种多线程访问方法及装置。
背景技术
在现代计算机程序编程中,多线程被广泛运用,为了保护相关的代码或者变量,在多线程中通常采用锁机制来解决。例如在Windows系统中可以采用临界区(CriticalSection),互斥体、信号量等方法来实现锁功能。以临界区为例,利用InitializeCriticalSection系统函数初始化一个临界区对象,然后利用EnterCriticalSection系统函数对临界区进行加锁,这样其他线程运行到调用该函数地址时,就会被阻塞;调用LeaveCriticalSection系统函数对该临界区进行解锁。位于EnterCriticalSection和LeaveCriticalSection之间的代码就是线程安全的,对于有N个线程同时运行的进程来说,同时只有一个线程能够访问到这之间的代码。
但是,在C++语言中,如果将一个类对象释放之后,任何访问该类对象的成员变量都会引起程序的崩溃。假设一个包含有临界区对象的类对象在一个线程中被释放了,而另外一个线程再去访问该类对象中的临界区对象时,进程就会崩溃。
发明内容
鉴于上述问题,提出了本发明以便提供一种克服上述问题或者至少部分地解决上述问题的多线程访问方法及装置。
本发明的一个方面,提供了一种多线程访问方法,所述方法包括:
响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系;
获取线程调用所述全局锁加锁时的键值;
判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器;
若所述全局键值对表中不存在与加锁时的键值对应的锁对象,则创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表;
调用所述全局临界区对象对所述全局键值对表进行解锁;
调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
其中,当所述线程完成对所述函数对象的访问后,所述方法还包括:
调用所述全局临界区对象对所述全局键值对表进行加锁;
获取线程调用所述全局锁解锁时的键值;
根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象;
调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一;
根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象;
调用所述全局临界区对象对所述全局键值对表进行解锁。
其中,在所述释放所述锁对象之后,所述方法还包括:
从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
其中,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。
本发明的另一个方面,提供了一种多线程访问装置,所述装置包括:
第一加锁模块,用于响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系;
获取模块,用于获取线程调用所述全局锁加锁时的键值;
判定模块,用于判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器;
配置模块,用于当所述全局键值对表中不存在所述键值对应的锁对象时,创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表;
第一解锁模块,用于调用所述全局临界区对象对所述全局键值对表进行解锁;
第二加锁模块,用于调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
其中,所述第一加锁模块,还用于当所述线程完成对所述函数对象的访问后,调用所述全局临界区对象对所述全局键值对表进行加锁;
所述获取模块,还用于获取线程调用所述全局锁解锁时的键值;
所述装置还包括:
查找模块,用于根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象;
第二解锁模块,用于调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一;
所述配置模块,还用于根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象;
所述第一解锁模块,还用于调用所述全局临界区对象对所述全局键值对表进行解锁。
其中,所述配置模块,还用于在释放所述锁对象之后,从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
其中,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。
此外,本发明还提供了一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现如上所述方法的步骤。
此外,本发明还提供了一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述程序时实现如上所述方法的步骤。
本发明实施例提供的多线程访问方法及装置,通过将全局锁配置在全局变量中,利用全局锁保证了多个访问线程中有且仅有一个线程能够获取到全局锁的锁对象,进而保证有且仅有一个线程能够访问同一函数对象,解决利用类成员锁实现线程访问过程中可能存在的野指针问题,避免可能引起的程序崩溃,保证了程序的运行稳定性。
此外,本发明实施例在线程获取全局锁时,创建新的锁对象并为锁对象生成用于记录锁对象引用次数的引用计数器,通过控制锁对象的引用计数,使得全局锁在不被使用后可以释放,减少资源的不必要占用,解决资源不断增加的问题。而且,在创建新的锁对象时,通过保证全局键值对表中不存在与创建新的锁对象的键值相同的锁对象,进一步避免了由于内存泄露以及上锁失败而导致的进程崩溃问题。
上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,而可依照说明书的内容予以实施,并且为了让本发明的上述和其它目的、特征和优点能够更明显易懂,以下特举本发明的具体实施方式。
附图说明
通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示相同的部件。在附图中:
图1为本发明实施例的一种多线程访问方法的流程图;
图2为本发明实施例的一种多线程访问装置的结构框图;
图3为本发明实施例的计算机设备的示意图。
具体实施方式
下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
本技术领域技术人员可以理解,除非另外定义,这里使用的所有术语(包括技术术语和科学术语),具有与本发明所属领域中的普通技术人员的一般理解相同的意义。还应该理解的是,诸如通用字典中定义的那些术语,应该被理解为具有与现有技术的上下文中的意义一致的意义,并且除非被特定定义,否则不会用理想化或过于正式的含义来解释。
图1示意性示出了本发明一个实施例的多线程访问方法的流程图。参照图1,本发明实施例的多线程访问方法具体包括以下步骤:
步骤S11、响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系。
其中,所述全局锁配置在预先创建的全局变量中,所述全局锁配置有全局键值对表和用于保护所述全局键值对表的全局临界区对象。
本实施例是一种通过采用全局锁解决多线程冲突的多线程访问方法,本实施例中的全局锁,即是通过将锁不放在任何类的成员中,而是放到一个全局变量中,这样使得该全局锁不属于任何一个类对象。本实施例中对于全局锁包括五个函数,分别为全局锁创建函数、GlobalLockNewInstance、全局加锁函数GlobalLockLock、全局解锁函数GlobalLockUnlock、锁对象引用计数加一函数GlobalLockAddRef、锁对象引用计数减一函数GlobalLockRelease。其中,在实现这些函数时,有一个共同的全局的键值对表,即全局键值对表g_globalLockDict,以及一个全局的临界区对象,即全局临界区对象g_globakLock,其中,全局锁的全局临界区对象用来保护全局键值对表。根据全局键值对表实现利用一个唯一的键值来获得全局锁的锁对象。
其中,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。本实施例中全局键值对表可以采用哈希表、线性表、或树状表实现,本发明对此不做限定。
步骤S12、获取线程调用所述全局锁加锁时的键值。
本实施例中,在线程对函数对象的访问时,线程调用的是全局锁的全局加锁函数GlobalLockLock,线程调用全局加锁函数时对应的键值确定了线程获取的锁对象。
步骤S13、判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器,若所述全局键值对表中不存在与加锁时的键值对应的锁对象,则执行步骤S14,否则,获取与加锁时的键值对应的锁对象,对获取到的锁对象对应的引用计数加1,并在步骤S15之后,调用获取的锁对象为所述线程访问的函数对象进行加锁。
步骤S14、创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表。
本实施例中当线程访问函数对象时,则调用全局锁的全局临界区对象对全局键值对表进行加锁,以保护全局键值对表不被其他线程修改,然后判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,若不存在则为当前线程创建一个新的锁对象,并为创建的锁对象生成用于记录锁对象引用次数的引用计数器。本实施例中通过为锁对象设置引用计数器,以供后续根据引用计数判断当前锁对象是否存在线程调用,使得全局锁可以在不被使用后可以释放,解决资源占用问题。而且,在创建新的锁对象时,通过保证全局键值对表中不存在与创建新的锁对象的键值相同的锁对象,进一步避免了由于内存泄露以及上锁失败而导致的进程崩溃问题。
步骤S15、调用所述全局临界区对象对所述全局键值对表进行解锁。
本实施例中,在创建新的锁对象的过程中,通过调用所述全局临界区对象对所述全局键值对表进行加、解锁,实现对全局键值对表的保护,进一步保证了锁对象的创建过程中,多个访问线程中有且仅有一个线程能够对全局键值对表进行访问,实现锁对象的创建。
步骤S16、调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
在完成新的锁对象的创建后,即可直接调用创建的新的锁对象为所述线程访问的函数对象进行加锁,使得有且仅有当前线程能够访问所述函数对象,保证了程序的运行稳定性。
本发明实施例提供的多线程访问方法,通过将全局锁配置在全局变量中,利用全局锁保证了多个访问线程中有且仅有一个线程能够获取到全局锁的锁对象,进而保证有且仅有一个线程能够访问同一函数对象,解决利用类成员锁实现线程访问过程中可能存在的野指针问题,避免可能引起的程序崩溃,保证了程序的运行稳定性。此外,本发明实施例在线程获取全局锁时,创建新的锁对象并为锁对象生成用于记录锁对象引用次数的引用计数器,通过控制锁对象的引用计数,使得全局锁在不被使用后可以释放,减少资源的不必要占用,解决资源不断增加的问题。而且,在创建新的锁对象时,通过保证全局键值对表中不存在与创建新的锁对象的键值相同的锁对象,进一步避免了由于内存泄露以及上锁失败而导致的进程崩溃问题。
本发明实施例中,在所述线程完成对所述函数对象的访问后,所述方法还包括以下附图中未示出的步骤:
步骤S21、调用所述全局临界区对象对所述全局键值对表进行加锁。
步骤S22、获取线程调用所述全局锁解锁时的键值。
本实施例中,当线程完成对函数对象的访问后,线程调用的是全局锁的全局解锁函数GlobalLockUnlock。可理解的,线程在对函数对象的一次访问过程中,在调用的是全局锁的全局加锁函数时和在调用的是全局锁的全局解锁函数时对应的键值必须一致。
步骤S23、根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象。
步骤S24、调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一。
步骤S25、根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象。
本实施例中,当调用锁对象进行解锁时,对锁对象的引用计数减一,当解锁完成后,则根据更新后的引用计数判断判定获取到的锁对象是否存在线程调用,若没有任何线程还会使用该锁对象,释放该锁对象,本实施例,通过对引用计数的判断,增加了释放该锁对象的判定条件,解决了全局锁创建之后不能释放的问题。
步骤S26、调用所述全局临界区对象对所述全局键值对表进行解锁。
本实施例中,在实现对锁对象的引用计数的更新过程中,通过再次调用所述全局临界区对象对所述全局键值对表进行加、解锁,实现对全局键值对表的保护,进一步保证了引用计数的更新过程中,多个访问线程中有且仅有一个线程能够对全局锁的锁对象的引用计数进行更新。
进一步地,在所述释放所述锁对象之后,从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
本实施例中,当调用锁对象进行加锁时,对锁对象的引用计数加一,当调用锁对象进行解锁时,对锁对象的引用计数减一,当解锁完成后判断该全局锁锁对象的引用计数是否为0,若引用计数等于0,则代表没有任何线程还会使用该锁对象,释放该锁对象,并从全局键值对表中移除该锁对象以及该锁对象和与其对应的键值之间的对应关系,解决了全局锁创建之后不能释放的问题。
为了一步一步的阐述本技术方案中的细节点,下面通过一个具体实施例对本发明技术进行说明。
本实施例通过以类A和类B为例,来说明本发明技术方案采用全局锁解决多线程冲突的多线程访问方法的具体实现方式和有益效果。这两个类的主要目的是模拟一种空闲对象的可回收机制,其中A是回收者,B是回收数据源,当B空闲后,将其再次回收到类A中,而当A要释放的时候,当B空闲后,则直接释放B,不再进行回收。
案例1:采用成员锁的情况
在类A中有一个临界区对象m_locker,并且有一个类B的对象指针数据列表m_list,该临界区对象保护该数据列表。
类B中有两个成员函数release,internalRelease,并且有一个指向类A的指针成员m_A,一个int类型的引用计数m_ref,以及一个临界区对象m_locker用来保护数据成员。
在类A析构的时候,对数据列表中的每一个B对象指针,调用其internalRelease函数对空闲的B对象进行释放。
类B的internalRelease函数中,首先利用m_locker进行加锁进行多线程保护,然后判断引用计数m_ref是否等于0,如果等于0则代表该对象是空闲的对象,从而释放,如果不等于0,则代表该对象仍然被其他的线程引用,不能被释放,并且将指向类A的成员m_A设置成0,等到该对象变成空闲后,就不再回收。
类B的release函数中,同样首先利用m_locker进行加锁进行多线程保护,然后对引用计数减一,然后判断引用计数是否等于0,如果等于0,继续判断m_A是否等于0,如果m_A不等于0,则再次将该对象保存到对象A的列表m_list中,如果m_A等于0则直接释放该对象。
类A的伪代码
类B的伪代码
上述的伪代码实现中,对于类B虽然利用m_locker锁对internalRelease和release函数进行了加锁,但是仍然存在下列的问题。
●解锁机制
上述B的实现中都是在internalRelease和release函数的最后对临界区进行解锁,但是如果上述两个函数中进入到delete this这段代码时,该类对象已经被释放,而在这两个函数的最后一行再次引用临界区对象时,可能引起程序崩溃。
●野指针
假设有线程1和线程2同时运行,线程1执行release函数,线程2执行internalRelease函数。根据线程1和线程2先后获得锁的顺序分以下两种情况进行讨论。
■线程1首先获得锁
线程1首先获得临界区进入到release函数中,此时线程2会被阻塞,线程1继续执行,原有的引用计数为1,在release函数中对引用计数自减1后,B对象变成空闲状态,而此时m_A成员不为0,则将B对象回收到类A的m_list数据列表中,release函数返回之后,临界区被解锁;此时线程2获得临界区锁,继续执行,此时引用计数已经等于0,就会释放该B对象,但是在release函数中已经把该B对象回收到了m_A中,这样就会造成m_A的数据列表m_list中保存有野指针(已经被删除的数据),从而引起程序崩溃。
■线程2首先获得锁
线程2首先获得临界区进入到internalRelease函数中,而线程1被阻塞,线程2中首先将m_A设置为0,此时引用计数不为0,不释放B对象,internalRelease返回之后,临界区被解锁;此时线程1获得临界区锁,继续执行,对引用计数自减1后,B对象变成空闲状态,而此时m_A成员为0,直接释放B,而不回收。此种情况下不会引起程序崩溃。
通过上面的例子,可以明显看出采取成员锁的时候,存在的多线程问题,对于造成的野指针问题,其问题就在于不能有两个线程同时进入到internalRelease以及release函数中,只要能够保证任何时候只有一个线程进入internalRelase或者release函数中,才能解决野指针的问题。所以在类B中采用成员锁来解决多线程的问题明显是不能够解决的。
下面给出的是利用本发明技术方案中的全局锁来解决多线程冲突的具体实现方法。
案例2:采用全局锁的情况
所谓全局锁,就是将锁不放在任何类的成员中,而是放到一个全局变量中,这样改全局锁不属于任何一个类对象。并且利用一个唯一的键来获得全局锁。本案中对于全局锁有两个函数,在实现这两个函数时,有一个全局的键值对表g_globalLockDict,以及一个全局的临界区对象g_globakLock,用来保护全局的键值对表。
GlobalLockLock(void*key)
参数key就是上述中唯一的键,该函数的实现过程如下:
调用g_globakLock进行加锁;
从全局键值对表中根据key查找对应的锁对象keyLock,如果没有找到则创建一个新的锁对象,并存放到全局键值对表g_globalLockDict中。
调用g_globakLock进行解锁;
调用keyLock进行加锁;
特别注意步骤c),如果步骤c在步骤d)后面调用,那么如果keyLock没有被解锁之前,g_globalLock也没有解锁,那么全局其他的线程都会被阻塞,这样加锁的粒度过大,对程序的性能造成极大影响。
GlobalLockUnlock(void*key)
同样参数key就是上述中唯一的键,该函数的实现过程如下:
调用g_globakLock进行加锁;
从全局键值对表中根据key查找对应的锁对象keyLock;
调用keyLock进行解锁;
调用g_globakLock进行解锁;
有了对全局锁实现的描述,利用全局锁,再来实现上面的类A和类B,具体如下:
类A的伪代码
类B的伪代码
从上面的伪代码中可以看到的是类A和类B中的临界区成员锁m_locker都被删除,类B中的m_staticA表示类A的指针值,作为全局锁的键。
类B的internalRelease实现上不需要再进行加锁,因为在类A的析构函数中已经加锁了。下面分析利用全局锁之后,是否解决了之前存在的野指针问题。
假设有线程1和线程2同时运行,线程1执行B的release函数,线程2执行类A的析构函数。根据线程1和线程2先后获得全局锁的顺序分以下两种情况进行讨论。
●线程1首先获得锁
线程1首先获得全局锁进入到release函数中,此时线程2会被阻塞,线程1继续执行,原有的引用计数为1,在release函数中对引用计数自减1后,B对象变成空闲状态,而此时m_A成员不为0,则将B对象回收到类A的m_list数据列表中,release函数返回之后,全局锁被解锁;此时线程2获得全局锁,继续执行,对A的数据成员m_list中的每一个B对象调用internalRelease函数,因为此时B的引用计数变为0,所以释放掉B,不会造成野指针问题。
●线程2首先获得锁
线程2首先获得临界区进入到类A的析构函数中,而线程1被阻塞,线程2对类A的数据成员m_list中的每一个B对象调用internalRelease函数中将m_A设置为0,此时引用计数不为0,不释放B对象,A对象析构完成之后,全局锁被解锁;此时线程1获得全局锁,继续执行,对引用计数自减1后,B对象变成空闲状态,而此时m_A成员为0,直接释放B,而不回收,同样不会引起多线程问题。
根据上面的分析,利用全局锁解决了案例1中利用成员锁,而引起的野指针问题。利用全局锁解决该问题的根本原因就在于对于N个线程保证了有且仅有一个线程能够进入同一个B对象的internalRelease或者release函数中。
本发明实施例利用全局锁的GlobalLockLock和GlobalLockUnlock函数解决了通常模式了利用类成员锁可能存在的多线程问题,保证了程序的运行稳定性。
虽然上述利用全局锁解决了线程冲突问题,但是在全局锁的实现上仍然有瑕疵,那就是在GlobalLockLock的实现上,当在g_globalLockDict中找不到键为key的锁对象时,就会创建一个所对象,并加入到g_globalLockDict全局键值对锁字典中。这样对于任何一个不同的key,都会不断的生成新的锁对象,而没有任何地方删除已经没有用的锁对象。这样会造成资源的不断增加。所以本发明实施例在此基础上对全局锁加入引用计数的方式,当某个全局锁的引用计数为0时,将该全局锁删除,并将其从g_globalLockDict全局键值对锁字典中移除。
本实施例中用一个结构为GlobalLockContext的结构来代表一个全局锁锁对象,全局锁锁对象中有一个字段为locker的互斥体对象,以及一个为refCount的引用计数字段。并提供GlobalLockNewInstance(创建一个全局锁)、GlobalLockLock(加锁)、GlobalLockUnlock(解锁)、GlobalLockAddRef(引用计数加一操作)、GlobalLockRelease(引用计数减一操作)函数对全局锁锁对象进行操作。
GlobalLockNewInstance(void*key)
该函数的功能是创建一个新的全局锁,实现步骤如下:
调用g_globalLock进行加锁;
创建一个GlobalLockContext对象,并将该对象的refCount字段设置为1;
将上述创建的对象存入到g_globalLockDict中;
调用g_globalLock进行解锁。
GlobalLockLock(void*key)
该函数的功能是对全局锁进行加锁,并且增加全局锁的引用计数,防止全局锁过早的被释放,实现步骤如下:
调用g_globalLock进行加锁;
根据key,从g_globalLockDict找到对应的GlobalLockContext对象;
对GlobalLockContext对象的refCount进行加一操作;
调用g_globalLock进行解锁;
调用GlobalLockContext对象中的locker对象的lock方法,进行加锁。
GlobalLockUnlock(void*key)
该函数的功能是对全局锁进行解锁,并对全局锁的引用计数减一,实现引用计数的平衡,实现步骤如下:
调用g_globalLock进行加锁;
根据key,从g_globalLockDict找到对应的GlobalLockContext对象;
调用GlobalLockContext对象中的locker对象的unlock方法,进行解锁;
对GlobalLockContext对象的refCount进行减一操作;
判断GlobalLockContext对象的refCount引用计数是否等于0,如果等于0,则代表没有任何线程还会使用该全局锁,可以释放该对象,并从g_globalLockDic移除该全局锁;
调用g_globalLock进行解锁。
GlobalLockAddRef(void*key)
该函数的功能是对全局锁的引用计数加一,实现步骤如下:
调用g_globalLock进行加锁;
根据key,从g_globalLockDict找到对应的GlobalLockContext对象;
对GlobalLockContext对象的refCount进行加一操作;
调用g_globalLock进行解锁。
GlobalLockRelease(void*key)
该函数的功能是对全局锁的引用计数进行减一,实现步骤如下:
调用g_globalLock进行加锁;
根据key,从g_globalLockDict找到对应的GlobalLockContext对象;
对GlobalLockContext对象的refCount进行减一操作;
判断GlobalLockContext对象的refCount引用计数是否等于0,如果等于0,则代表没有任何线程还会使用该全局锁,可以释放该对象,并从g_globalLockDic移除该全局锁;
调用g_globalLock进行解锁;
上述完整的阐述了带引用计数的全局锁实现,根据该带引用计数的全局锁,再来看类A和类B的伪代码实现:
类A的伪代码
类B的伪代码
在类A的构造函数中,调用GlobalLockNewInstance创建了一个全局锁,在类A的析构函数中调用GlobalLockRelease函数对该全局锁的引用计数减一;在类B的构造函数中,调用GlobalLockAddRef对全局锁的引用计数加一,在类B的析构函数中,调用GlobalLockRelease对全局锁的引用计数减一,当类A对象和所有的类B对象都释放之后,该全局锁的引用计数变为0,从而释放该全局锁。解决了全局锁创建之后不能释放的问题。
上述带引用计数的全局锁实现中,任然存在一个的漏洞。该漏洞可能会导致对于GlobalLockLock函数的调用,起不到任何的加锁功能,进而导致利用全局锁在多线程应用中出现各种各样的多线程bug。该漏洞的根源就在于GlobalLockNewInstance的实现上,该函数的功能是根据一个指定的key,创建一个全局锁,其原来的实现过程如下:
调用g_globalLock进行加锁;
创建一个GlobalLockContext对象,并将该对象的refCount字段设置为1;
将上述创建的对象存入到g_globalLockDict中;
调用g_globalLock进行解锁。
该GlobalLockNewInstance函数的实现过程中,问题就出在步骤c),在该步骤中将创建的GlobalLockContext对象以及GlobalLockNewIntance的函数参数key以键值对的方式,存入到全局字典g_globalLockDict中。但是g_globalLockDict字典对于添加键值对是有条件的,那就是键不能重复,也就是说如果g_globalLockDict字典中已经有了以key为键的键值对项,那么在步骤c)中将步骤b)中新创建的GlobalLockContext添加到g_globalLockDict字典时,就会失败,那么就会引起下面的两个漏洞:
1、存在内存泄露
因为新创建的GlobalLockContext添加到g_globalLockDict中失败了,那么该GlobalLockContext就不会受到任何的管理,成为了不受GlobalLockRelease和GlobalLockUnlock管理的对象,因为GlobalLockContext的释放只有在其引用计数为0时会被删除,而该项功能只有在GlobakLockUnlock以及GlobalLockRelease中实现。所以如果新创建的GlobalLockContext没有添加到g_globalLockDict中进行管理,那么必然存在该内存泄露。
2、存在GlobalLockLock失败的情况
该漏洞比上述的内存泄露更为严重。因为该漏洞可能会导致GlobalLockLock在g_globalLockDict字典中找不到其参数key指定的GlobalLockContext项,从而导致无法加锁,那么就会出现各种各样的多线程问题,最终导致进程崩溃。导致该问题的原因是:如果key关联的GlobalLockContext的引用计数被减少到0了,那么该GlobalLockContext自然就会从g_globalLockDict字典中移除并释放掉。例如下面的例子中,创建一个A对象,以及三个B对象,在A的构造函数中调用了GlobalLockNewInstance来创建一个全局锁:
A*a1=new A;
B*b1=new B;
B*b2=new B;
B*b3=new B;
现在该全局锁GlobalLockContext的引用计数为4(因为B的构造函数中调用了GlobalLockAddRef来增加引用计数),
接下来增加b1,即
b1->addRef(),此时b1的引用计数为1(B的构造函数中,将引用计数初始化为0),而b2、b3的引用计数都为0
接下来,删除a1,将a1对象释放掉;
delete a1;
那么此时该全局锁GlobalLockContext的引用计数为1(因为在释放a1对象时,会调用其析构函数,并在析构函数中,将所有引用计数为0的B对象都释放掉,也就是将b2、b3释放掉,并且在释放B对象时,会调用到B对象的析构函数中,从而调用GlobalLockRelease将GlobalLockContext的引用计数减1,因为b1还没有释放掉,所以此时GlobalLockContext的引用计数为1)
接下来,在创建一个A对象,标记为a2
A*a2=new A;
此时可能存在的问题,因为在C++的内存分配中,如果分配的内存大小是一致的,那么极有可能导致分配后的地址与之前已经释放后的地址一致。也就是说a2对象的地址极有可能与a1对象的地址是一样的,如果是一样的,那么在创建a2时,其构造函数中调用GlobalLockNewInstance就会出现本案中的情形。因为此时的key值,也就是a2的this指针与a1是一致的,但是此时的g_globalLockDict中已经存在了key值为a1地址的GlobalLockContext,并且该GlobalLockContext的引用计数为1.。所以a2调用GlobalLockNewInstance完成之后,此时g_globalLockDict中仍然只有一个引用计数为1的GlobalLockContext项。
接下来,将上面的b1释放掉,即
b1->release();
那么此时b1就会被释放掉,并调用GlobalLockRelease对GlobalLockContext引用计数减1,此时GlobalLockContext的引用计数为0,并从g_globalLockDict字典中移除了。
那么此时在a2对象中,再次调用GlobalLockLock函数时,就找不到GlobalLockContext了,从而导致GlobalLockLock函数没有成功上锁。
通过对上述两个漏洞的分析,已经清楚的知道了GlobalLockNewInstance函数实现的问题,下面即采用本发明实施例提供的所线程访问方法来解决该漏,具体如下:
a)调用g_globalLock进行加锁;
b)判断g_globalLockDict中是否存在参数key指定的GlobalLockContext项,如果不存在进入步骤c),如果存在进入到步骤e);
c)进入到该步骤则说明g_globalLockDict中不存在参数key指定的GlobalLockContext项,那就创建一个新的GlobalLockContext对象,并将该对象的refCount字段设置为1,并进入到下面的步骤d);
d)将上述创建的对象存入到g_globalLockDict中,并进入到步骤f);
e)进入到该步骤则说明g_globalLockDict中存在参数key指定的GlobalLockContext项,此时需要增加已经存在的GlobalLockContext的引用计数,即将该GlobalLockContext的引用计数在现有基础上加一。完成之后,进入到步骤f);
f)调用g_globalLock进行解锁。
通过上面的改进,仍然再来分析上述中的例子:
delete a1;此时GlobalLockContext的引用计数为1;
再创建a2对象,假设a2对象的地址与a1对象的地址一致;
A*a2=new A;那么在调用GlobalLockNewInstance时,在上述的步骤b)中发现指定key的GlobalLockContext存在,就会进入到步骤e)里面,并对该存在的GlobalLockContext的引入计数加1,那么此时的GlobalLockContext的引用计数为2。
接下来释放b1;
b1->release();此时调用GlobalLockRelease对GlobalLockContext的引用计数减1,那么现在该GlobalLockContext的引用计数为1,就不会被删除。
那么此时在a2对象中继续调用GlobalLockLock时,仍然能够找到该GlobalLockContext项,从而GlobalLockLock函数能够成功上锁,就不会出现多线程问题。
利用本案中全局锁的GlobalLockLock和GlobalLockUnlock函数解决了通常模式了利用类成员锁可能存在的多线程问题,保证了程序的运行稳定性,并利用GlobalLockAddRef,GlobalLockRelease函数控制全局锁的引用计数,使得全局锁可以在不被使用后可以释放,解决了资源不断增加的问题,并且解决了GlobalLockNewInstance函数中存在的缺陷,导致内存泄露以及上锁失败,从而出现因为多线程问题而导致的进程崩溃问题。
对于方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明实施例并不受所描述的动作顺序的限制,因为依据本发明实施例,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作并不一定是本发明实施例所必须的。
图2示意性示出了本发明一个实施例的多线程访问装置的结构示意图。参照图2,本发明实施例的多线程访问装置具体包括第一加锁模块201、获取模块202、判定模块203、配置模块204、第一解锁模块205以及第二加锁模块206,其中:
第一加锁模块201,用于响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系;其中,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。
获取模块202,用于获取线程调用所述全局锁加锁时的键值;
判定模块203,用于判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器;
配置模块204,用于当所述全局键值对表中不存在所述键值对应的锁对象时,创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表;
第一解锁模块205,用于调用所述全局临界区对象对所述全局键值对表进行解锁;
第二加锁模块206,用于调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
本发明实施例中,所述第一加锁模块201,还用于当所述线程完成对所述函数对象的访问后,调用所述全局临界区对象对所述全局键值对表进行加锁;
所述获取模块202,还用于获取线程调用所述全局锁解锁时的键值;
所述装置还包括附图中未示出的查找模块和第二解锁模块:
所述查找模块,用于根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象;
第二解锁模块,用于调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一;
所述配置模块204,还用于根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象;
所述第一解锁模块205,还用于调用所述全局临界区对象对所述全局键值对表进行解锁。
进一步地,所述配置模块204,还用于在释放所述锁对象之后,从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
对于装置实施例而言,由于其与方法实施例基本相似,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
以上所描述的装置实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性的劳动的情况下,即可以理解并实施。
本发明实施例提供的多线程访问方法及装置,通过将全局锁配置在全局变量中,利用全局锁保证了多个访问线程中有且仅有一个线程能够获取到全局锁的锁对象,进而保证有且仅有一个线程能够访问同一函数对象,解决利用类成员锁实现线程访问过程中可能存在的野指针问题,避免可能引起的程序崩溃,保证了程序的运行稳定性。
此外,本发明实施例在线程获取全局锁时,创建新的锁对象并为锁对象生成用于记录锁对象引用次数的引用计数器,通过控制锁对象的引用计数,使得全局锁在不被使用后可以释放,减少资源的不必要占用,解决资源不断增加的问题。而且,在创建新的锁对象时,通过保证全局键值对表中不存在与创建新的锁对象的键值相同的锁对象,进一步避免了由于内存泄露以及上锁失败而导致的进程崩溃问题。
此外,本发明实施例还提供了一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现如上所述方法的步骤。
本实施例中,所述多线程访问装置集成的模块/单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明实现上述实施例方法中的全部或部分流程,也可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一计算机可读存储介质中,该计算机程序在被处理器执行时,可实现上述各个方法实施例的步骤。其中,所述计算机程序包括计算机程序代码,所述计算机程序代码可以为源代码形式、对象代码形式、可执行文件或某些中间形式等。所述计算机可读介质可以包括:能够携带所述计算机程序代码的任何实体或装置、记录介质、U盘、移动硬盘、磁碟、光盘、计算机存储器、只读存储器(ROM,Read-OnlyMemory)、随机存取存储器(RAM,Random Access Memory)、电载波信号、电信信号以及软件分发介质等。需要说明的是,所述计算机可读介质包含的内容可以根据司法管辖区内立法和专利实践的要求进行适当的增减,例如在某些司法管辖区,根据立法和专利实践,计算机可读介质不包括电载波信号和电信信号。
图3为本发明实施例提供的计算机设备的示意图。本发明实施例提供的计算机设备,包括存储器301、处理器302及存储在存储器301上并可在处理器302上运行的计算机程序,所述处理器302执行所述计算机程序时实现上述各个多线程访问方法实施例中的步骤,例如图1所示的各个步骤。或者,所述处理器302执行所述计算机程序时实现上述各多线程访问装置实施例中各模块/单元的功能,例如图2所示的第一加锁模块201、获取模块202、判定模块203、配置模块204、第一解锁模块205以及第二加锁模块206。
示例性的,所述计算机程序可以被分割成一个或多个模块/单元,所述一个或者多个模块/单元被存储在所述存储器中,并由所述处理器执行,以完成本发明。所述一个或多个模块/单元可以是能够完成特定功能的一系列计算机程序指令段,该指令段用于描述所述计算机程序在所述多线程访问装置中的执行过程。例如,所述计算机程序可以被分割成第一加锁模块201、获取模块202、判定模块203、配置模块204、第一解锁模块205以及第二加锁模块206。
所述计算机设备可以是桌上型计算机、笔记本、掌上电脑及云端服务器等计算设备。所述计算机设备可包括,但不仅限于,处理器、存储器。本领域技术人员可以理解,所述示意图3仅仅是计算机设备的示例,并不构成对计算机设备的限定,可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件,例如所述计算机设备还可以包括输入输出设备、网络接入设备、总线等。
所述处理器可以是中央处理单元(Central Processing Unit,CPU),还可以是其他通用处理器、数字信号处理器(Digital Signal Processor,DSP)、专用集成电路(Application Specific Integrated Circuit,ASIC)、现成可编程门阵列(Field-Programmable Gate Array,FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等,所述处理器是所述计算机设备的控制中心,利用各种接口和线路连接整个计算机设备的各个部分。
所述存储器可用于存储所述计算机程序和/或模块,所述处理器通过运行或执行存储在所述存储器内的计算机程序和/或模块,以及调用存储在存储器内的数据,实现所述计算机设备的各种功能。所述存储器可主要包括存储程序区和存储数据区,其中,存储程序区可存储操作系统、至少一个功能所需的应用程序(比如声音播放功能、图像播放功能等)等;存储数据区可存储根据手机的使用所创建的数据(比如音频数据、电话本等)等。此外,存储器可以包括高速随机存取存储器,还可以包括非易失性存储器,例如硬盘、内存、插接式硬盘,智能存储卡(Smart Media Card,SMC),安全数字(Secure Digital,SD)卡,闪存卡(Flash Card)、至少一个磁盘存储器件、闪存器件、或其他易失性固态存储器件。
本领域的技术人员能够理解,尽管在此的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。例如,在下面的权利要求书中,所要求保护的实施例的任意之一都可以以任意的组合方式来使用。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。
Claims (10)
1.一种多线程访问方法,其特征在于,所述方法包括:
响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系;
获取线程调用所述全局锁加锁时的键值;
判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器;
若所述全局键值对表中不存在与加锁时的键值对应的锁对象,则创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表;
调用所述全局临界区对象对所述全局键值对表进行解锁;
调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
2.根据权利要求1所述的方法,其特征在于,当所述线程完成对所述函数对象的访问后,所述方法还包括:
调用所述全局临界区对象对所述全局键值对表进行加锁;
获取线程调用所述全局锁解锁时的键值;
根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象;
调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一;
根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象;
调用所述全局临界区对象对所述全局键值对表进行解锁。
3.根据权利要求2所述的方法,其特征在于,在所述释放所述锁对象之后,所述方法还包括:
从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
4.根据权利要求1-3任一项所述的方法,其特征在于,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。
5.一种多线程访问装置,其特征在于,所述装置包括:
第一加锁模块,用于响应于线程对函数对象的访问,调用全局锁的全局临界区对象对全局键值对表进行加锁,所述全局锁配置在预先创建的全局变量中,所述全局键值对表包括锁对象和与其对应的键值之间的对应关系;
获取模块,用于获取线程调用所述全局锁加锁时的键值;
判定模块,用于判定所述全局键值对表中是否存在与加锁时的键值对应的锁对象,所述全局键值对表中的每一锁对象设置有用于记录引用次数的引用计数器;
配置模块,用于当所述全局键值对表中不存在所述键值对应的锁对象时,创建新的锁对象,为所述新的锁对象生成引用计数器并将该引用计数器的计数值加1,并将创建的锁对象以及所述锁对象与指定的键值之间的对应关系添加到所述全局键值对表;
第一解锁模块,用于调用所述全局临界区对象对所述全局键值对表进行解锁;
第二加锁模块,用于调用创建的新的锁对象为所述线程访问的函数对象进行加锁。
6.根据权利要求5所述的装置,其特征在于,所述第一加锁模块,还用于当所述线程完成对所述函数对象的访问后,调用所述全局临界区对象对所述全局键值对表进行加锁;
所述获取模块,还用于获取线程调用所述全局锁解锁时的键值;
所述装置还包括:
查找模块,用于根据解锁时的键值查找所述全局键值对表,以获取与所述解锁时的键值对应的锁对象;
第二解锁模块,用于调用获取到的锁对象对所述线程访问的函数对象进行解锁,并对获取到的锁对象的引用计数器的计数值减一;
所述配置模块,还用于根据更新后的引用计数判定获取到的锁对象是否存在线程调用,若获取到的锁对象不存在线程调用,则释放该锁对象;
所述第一解锁模块,还用于调用所述全局临界区对象对所述全局键值对表进行解锁。
7.根据权利要求6所述的装置,其特征在于,所述配置模块,还用于在释放所述锁对象之后,从所述全局键值对表中移除所述锁对象以及所述锁对象和与其对应的键值之间的对应关系。
8.根据权利要求5-7任一项所述的装置,其特征在于,所述全局键值对表为哈希表、线性表、或树状表中的任意一个。
9.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,该程序被处理器执行时实现如权利要求1-4任一项所述方法的步骤。
10.一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,其特征在于,所述处理器执行所述程序时实现如权利要求1-4任一项所述方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810326813.8A CN108874446B (zh) | 2018-04-12 | 2018-04-12 | 多线程访问方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810326813.8A CN108874446B (zh) | 2018-04-12 | 2018-04-12 | 多线程访问方法及装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN108874446A true CN108874446A (zh) | 2018-11-23 |
CN108874446B CN108874446B (zh) | 2020-10-16 |
Family
ID=64326360
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810326813.8A Active CN108874446B (zh) | 2018-04-12 | 2018-04-12 | 多线程访问方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108874446B (zh) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109710629A (zh) * | 2019-01-08 | 2019-05-03 | 上海达梦数据库有限公司 | 数据访问方法、装置、服务器和存储介质 |
CN109710530A (zh) * | 2018-12-28 | 2019-05-03 | 珠海西山居互动娱乐科技有限公司 | 一种检测对象的内存泄漏的方法及装置 |
CN111723250A (zh) * | 2020-05-22 | 2020-09-29 | 长沙新弘软件有限公司 | 一种基于引用计数的链表管理方法 |
CN113961364A (zh) * | 2021-10-12 | 2022-01-21 | 西安热工研究院有限公司 | 一种大规模锁系统实现方法、装置、存储介质和服务器 |
Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102446226A (zh) * | 2012-01-16 | 2012-05-09 | 上海方正数字出版技术有限公司 | 一种实现NoSQL的键值存储引擎的方法 |
US20120272246A1 (en) * | 2010-12-06 | 2012-10-25 | International Business Machines Corporation | Dynamically scalable per-cpu counters |
CN103049305A (zh) * | 2012-08-03 | 2013-04-17 | 北京航空航天大学 | 针对龙芯多核cpu模拟的动态代码转换的多线程化方法 |
US8458721B2 (en) * | 2011-06-02 | 2013-06-04 | Oracle International Corporation | System and method for implementing hierarchical queue-based locks using flat combining |
CN103324269A (zh) * | 2013-06-13 | 2013-09-25 | 中国科学院计算技术研究所 | 一种降低多线程程序功耗的方法及系统 |
CN106537329A (zh) * | 2014-07-08 | 2017-03-22 | Arm 有限公司 | 用于为多线程执行锁保护处理操作的数据处理装置及方法 |
-
2018
- 2018-04-12 CN CN201810326813.8A patent/CN108874446B/zh active Active
Patent Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20120272246A1 (en) * | 2010-12-06 | 2012-10-25 | International Business Machines Corporation | Dynamically scalable per-cpu counters |
US8458721B2 (en) * | 2011-06-02 | 2013-06-04 | Oracle International Corporation | System and method for implementing hierarchical queue-based locks using flat combining |
CN102446226A (zh) * | 2012-01-16 | 2012-05-09 | 上海方正数字出版技术有限公司 | 一种实现NoSQL的键值存储引擎的方法 |
CN103049305A (zh) * | 2012-08-03 | 2013-04-17 | 北京航空航天大学 | 针对龙芯多核cpu模拟的动态代码转换的多线程化方法 |
CN103324269A (zh) * | 2013-06-13 | 2013-09-25 | 中国科学院计算技术研究所 | 一种降低多线程程序功耗的方法及系统 |
CN106537329A (zh) * | 2014-07-08 | 2017-03-22 | Arm 有限公司 | 用于为多线程执行锁保护处理操作的数据处理装置及方法 |
Cited By (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109710530A (zh) * | 2018-12-28 | 2019-05-03 | 珠海西山居互动娱乐科技有限公司 | 一种检测对象的内存泄漏的方法及装置 |
CN109710629A (zh) * | 2019-01-08 | 2019-05-03 | 上海达梦数据库有限公司 | 数据访问方法、装置、服务器和存储介质 |
CN109710629B (zh) * | 2019-01-08 | 2020-12-18 | 上海达梦数据库有限公司 | 数据访问方法、装置、服务器和存储介质 |
CN111723250A (zh) * | 2020-05-22 | 2020-09-29 | 长沙新弘软件有限公司 | 一种基于引用计数的链表管理方法 |
CN111723250B (zh) * | 2020-05-22 | 2024-03-08 | 长沙新弘软件有限公司 | 一种基于引用计数的链表管理方法 |
CN113961364A (zh) * | 2021-10-12 | 2022-01-21 | 西安热工研究院有限公司 | 一种大规模锁系统实现方法、装置、存储介质和服务器 |
Also Published As
Publication number | Publication date |
---|---|
CN108874446B (zh) | 2020-10-16 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108874446A (zh) | 多线程访问方法及装置 | |
US10360523B2 (en) | System and method for executing business services and enhancing business performance through a business process modeling notation | |
CN109344153B (zh) | 业务数据的处理方法及终端设备 | |
CN108762942A (zh) | 多线程访问方法及装置 | |
CN111931172B (zh) | 一种金融系统业务流程异常预警方法及装置 | |
CN111179066B (zh) | 业务数据的批量处理方法、装置、服务器和存储介质 | |
CN112669155A (zh) | 基于区块链的交易分发执行方法、装置服务器及存储介质 | |
CN108762940A (zh) | 多线程访问方法及装置 | |
CN107402821A (zh) | 共享资源的访问控制方法、装置和设备 | |
CN112597762B (zh) | 一种具有智能合约数据监管功能的区块链系统及监管方法 | |
CN108446181A (zh) | 对资源限制访问的方法、装置及终端设备 | |
CN111241526B (zh) | 数据权限匹配方法、装置、电子设备及存储介质 | |
CN115952162A (zh) | 一种数据质量校验方法、装置和设备 | |
US8789060B1 (en) | Deterministic, parallel execution with overlapping regions | |
CN108762941A (zh) | 多线程访问方法及装置 | |
CN116109114B (zh) | 一种常态化政务服务数据处理方法及系统 | |
CN111767337B (zh) | 区块的验证方法、装置及设备 | |
US20170024745A1 (en) | Network management event escalation | |
CN115878336A (zh) | 锁操作中的信息处理方法、装置及计算设备 | |
CN113961364A (zh) | 一种大规模锁系统实现方法、装置、存储介质和服务器 | |
US20160196331A1 (en) | Reconstitution order of entity evaluations | |
CN112291241A (zh) | 防火墙开墙方法、防火墙开墙装置及终端设备 | |
CN110516432A (zh) | 一种车辆权限的确定方法、装置、设备及存储介质 | |
CN111814007B (zh) | 双向链表数据处理方法、装置、设备及机器可读存储介质 | |
CN112667652B (zh) | 基于区块链的模拟交易方法、装置、设备和可读存储介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |