一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及計(jì)算機(jī)應(yīng)用領(lǐng)域,尤其涉及一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法。
【背景技術(shù)】
[0002]在傳統(tǒng)的數(shù)據(jù)并發(fā)采集系統(tǒng)中,使用基于鎖的生產(chǎn)者一消費(fèi)者緩沖區(qū)隊(duì)列模型,同一時(shí)間只能有一個(gè)線程獲得數(shù)據(jù)隊(duì)列緩沖區(qū)?;阪i的數(shù)據(jù)結(jié)構(gòu)能夠部分解決多線程成并發(fā)的問題,但是由于鎖結(jié)構(gòu)本身依賴與操作系統(tǒng)內(nèi)核的實(shí)現(xiàn)方式,獲得鎖和釋放鎖設(shè)計(jì)線程從用戶態(tài)到內(nèi)核態(tài)的上下文切換問題,而且鎖粒度大小難以控制,因此,在并發(fā)程序中的性能問題也逐漸顯露。
[0003]阻塞型算法試圖用不同形式的鎖(Lock)來解決并行算法遇到的訪問沖突問題,但是這種方法存在著死鎖、活鎖、條件競(jìng)爭(zhēng)等多種多樣的問題,為了解決這些問題,另一種并行算法一一非阻塞型算法被提出來。非阻塞型算法一般要滿足如下的前進(jìn)條件之一:
(O無(wú)等待條件(wait-free):該條件要求當(dāng)前線程的任務(wù)在有限步驟內(nèi)完成,在任務(wù)所有的操作完成前,并不管其他線程的任何操作。也就是說把只有當(dāng)前線程的所有操作完成之后,其他的線程才能開始任務(wù),但在現(xiàn)實(shí)中一個(gè)線程的任務(wù)數(shù)量可能很大,這種方法十分依賴線程的數(shù)目,因此在實(shí)際中應(yīng)用的比較少;
(2)無(wú)鎖條件(lock-free):該條件要求當(dāng)前線程的任務(wù)能夠在有限的步驟內(nèi)完成,但是不同于無(wú)等待模型的是,每一次線程執(zhí)行時(shí)只用保證完成部分操作。這就保證了多任務(wù)的調(diào)度順利,因此在大多數(shù)的無(wú)鎖數(shù)據(jù)結(jié)構(gòu)都是采用此種模型;
(3)無(wú)干擾條件(obstruct1n-free):該條件同樣要求線程能夠在有限的步驟內(nèi)完成,同時(shí)要求當(dāng)前線程被其它線程影響后能夠繼續(xù)執(zhí)行。
[0004]這些條件中的每一個(gè)都能夠保證能實(shí)現(xiàn)和阻塞鎖達(dá)到的要求,但是在實(shí)踐中條件越嚴(yán)苛的實(shí)現(xiàn)起來的代價(jià)就越高,但是性能也越好,目前主要的研宄集中在滿足無(wú)鎖(lock-free)條件的并發(fā)數(shù)據(jù)結(jié)構(gòu)上面。
[0005]無(wú)鎖(lock-free)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)基礎(chǔ)是高級(jí)別的原子操作(High-level atomic
operat1n),原子操作提供一個(gè)一致性接口:要么操作完成,要么操作失敗什么也不做--
如果操作失敗,用戶必須重試,失敗后進(jìn)行其他操作,因此用原子操作實(shí)現(xiàn)共享資源使用的線性化進(jìn)而實(shí)現(xiàn)無(wú)鎖數(shù)據(jù)結(jié)構(gòu)成為研宄者的首選。這其中CAS (Compare-And-Swap)操作更加簡(jiǎn)潔和高效,用它能夠?qū)崿F(xiàn)解決多線程無(wú)鎖同步問題。
【發(fā)明內(nèi)容】
[0006]本發(fā)明的目的在于針對(duì)現(xiàn)有技術(shù)的不足,提供一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法。
[0007]本發(fā)明的目的是通過以下技術(shù)方案來來實(shí)現(xiàn)的:一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,包括以下步驟:
(I)建立生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型;所述生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型包括采集部分和處理部分,采集部分和處理部分并行進(jìn)行;
(2)建立數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程;
(3)使用有序堆建立數(shù)據(jù)緩沖區(qū),數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳有序排放,數(shù)據(jù)緩沖區(qū)容量固定,數(shù)據(jù)節(jié)點(diǎn)在邏輯上是樹形結(jié)構(gòu);
(4)數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程對(duì)緩沖區(qū)進(jìn)行同步操作,操作完成后緩沖區(qū)恢復(fù)有序;
(5)使用CAS原子操作實(shí)現(xiàn)對(duì)緩沖區(qū)的無(wú)鎖增加、刪除和排序,實(shí)現(xiàn)線程同步操作,避免兩組工作線程阻塞。
[0008]進(jìn)一步地,所述步驟(2)中,生產(chǎn)者和消費(fèi)者可能是單一線程也可能是一組工作線程,兩個(gè)線程單獨(dú)工作互不影響。
[0009]進(jìn)一步地,所述步驟(4)具體為:生產(chǎn)者采集數(shù)據(jù)存入數(shù)據(jù)緩沖區(qū),若緩沖區(qū)不滿,將生產(chǎn)者采集的數(shù)據(jù)直接放入緩沖區(qū)的末尾,并且對(duì)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)滿,生產(chǎn)者采集的數(shù)據(jù)與緩沖區(qū)中時(shí)間戳最舊的數(shù)據(jù)交換后按時(shí)間戳自動(dòng)排序;消費(fèi)者從數(shù)據(jù)緩沖區(qū)取數(shù)據(jù),若緩沖區(qū)不空,將緩沖區(qū)中時(shí)間戳最新的數(shù)據(jù)取出,并且對(duì)緩沖區(qū)中剩余數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)空,則等待生產(chǎn)者采集的數(shù)據(jù)。
[0010]本發(fā)明的有益效果是:本發(fā)明使用生產(chǎn)者-消費(fèi)者緩沖區(qū)實(shí)現(xiàn)有序的數(shù)據(jù)排列,并且能夠以無(wú)鎖的方式實(shí)現(xiàn)兩部分線程的同步訪問而不出現(xiàn)數(shù)據(jù)污染和沖突。
【附圖說明】
[0011]圖1無(wú)鎖緩沖區(qū)的插入算法流程圖;
圖2無(wú)鎖緩沖區(qū)的刪除算法流程圖。
【具體實(shí)施方式】
[0012]下面結(jié)合附圖和具體實(shí)施例對(duì)本發(fā)明作進(jìn)一步詳細(xì)說明。
[0013]本發(fā)明一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,包括以下步驟:
(1)建立生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型;所述生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型包括采集部分和處理部分,采集部分和處理部分并行進(jìn)行;
(2)建立數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程;生產(chǎn)者和消費(fèi)者可能是單一線程也可能是一組工作線程,兩個(gè)線程單獨(dú)工作互不影響。
[0014](3)使用有序堆建立數(shù)據(jù)緩沖區(qū),數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳有序排放,數(shù)據(jù)緩沖區(qū)容量固定,數(shù)據(jù)節(jié)點(diǎn)在邏輯上是樹形結(jié)構(gòu);
(4)數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程對(duì)緩沖區(qū)進(jìn)行同步操作,操作完成后緩沖區(qū)恢復(fù)有序;具體為:生產(chǎn)者采集數(shù)據(jù)存入數(shù)據(jù)緩沖區(qū),若緩沖區(qū)不滿,將生產(chǎn)者采集的數(shù)據(jù)直接放入緩沖區(qū)的末尾,并且對(duì)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)滿,生產(chǎn)者采集的數(shù)據(jù)與緩沖區(qū)中時(shí)間戳最舊的數(shù)據(jù)交換后按時(shí)間戳自動(dòng)排序;消費(fèi)者從數(shù)據(jù)緩沖區(qū)取數(shù)據(jù),若緩沖區(qū)不空,將緩沖區(qū)中時(shí)間戳最新的數(shù)據(jù)取出,并且對(duì)緩沖區(qū)中剩余數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)空,則等待生產(chǎn)者采集的數(shù)據(jù)。
[0015](5)使用CAS原子操作實(shí)現(xiàn)對(duì)緩沖區(qū)的無(wú)鎖增加、刪除和排序,實(shí)現(xiàn)線程同步操作,避免兩組工作線程阻塞。實(shí)施例
[0016]利用定長(zhǎng)數(shù)組實(shí)現(xiàn)堆(Heap),此時(shí)數(shù)組成為一種平衡二叉樹。數(shù)組的第一個(gè)元素是樹的根,數(shù)組的第二三個(gè)節(jié)點(diǎn)分別是樹的左右孩子。這樣樹的索引非常方便,假如當(dāng)前節(jié)點(diǎn)的索引值為i的話,那么他的雙親節(jié)點(diǎn)為:iParent = floor ((1-1) / 2);左孩子節(jié)點(diǎn)為:iLeftChild= 2*i + I ;右孩子節(jié)點(diǎn)為:iRightChild = 2*i + 2。插入的過程就是一個(gè)不斷進(jìn)行堆化的過程,每次插入一個(gè)節(jié)點(diǎn)同時(shí)刪除一個(gè)節(jié)點(diǎn),不僅能夠保持元素的相對(duì)有序,而且不用進(jìn)行顯式的刪除元素的操作。
[0017]無(wú)鎖堆的數(shù)據(jù)結(jié)構(gòu)如代碼LockFreeHeap所示,包含一個(gè)恒定的數(shù)組以及保持修改狀態(tài)的變量N,和數(shù)組的長(zhǎng)度LEN,該無(wú)鎖堆在第一次使用時(shí)分配恒定的內(nèi)存,在使用的過程中,內(nèi)存不會(huì)重新分配與釋放。值得注意的是這里使用了另外一個(gè)顯式的狀態(tài)變量,這個(gè)變量叫做排序狀態(tài),它的作用是保證當(dāng)前只有一個(gè)線程能夠?qū)Χ堰M(jìn)行堆化操作
class LockFreeHeap{
Key* buffer; //存儲(chǔ)元素的數(shù)組
int N = O; //元素的最大索引,第O個(gè)位置不用
int LEN=1; //數(shù)組的最大長(zhǎng)度
bool status=0;//堆所處的狀態(tài):0,未交換狀態(tài);1,交換狀態(tài) };
當(dāng)生產(chǎn)者獲取數(shù)據(jù)節(jié)點(diǎn)時(shí),向LockFreeHeap中添加元素,普通的堆實(shí)現(xiàn)方法要在這時(shí)對(duì)堆進(jìn)行堆化,使堆相對(duì)有序,但是這不能進(jìn)行堆化,原因是堆化的過程是一個(gè)元素位置交換的過程,如果此時(shí)進(jìn)行堆化,當(dāng)消費(fèi)者同時(shí)也在進(jìn)行堆化的時(shí)候就會(huì)造成堆混亂。因此這里的堆化操作應(yīng)該只由消費(fèi)者獲得節(jié)點(diǎn)數(shù)據(jù)后單獨(dú)進(jìn)行堆化,這個(gè)過程中不能產(chǎn)生新的節(jié)點(diǎn),因此要對(duì)其進(jìn)行CAS索引保護(hù),這樣生產(chǎn)者就不能進(jìn)行增加測(cè)點(diǎn)的工作。
[0018]生產(chǎn)者線程插入數(shù)據(jù)的算法如圖1所示,在緩沖區(qū)不滿的時(shí)候,直接插入到緩沖區(qū)的末尾;當(dāng)緩沖區(qū)已滿的時(shí)候則要首先找到掉緩沖區(qū)中時(shí)間戳最舊元素,并與之交換信息,交換信息的過程中,保持無(wú)鎖堆狀態(tài)不能改變,因此用CAS操作來監(jiān)測(cè)無(wú)鎖堆的狀態(tài),直到確定其他的線程都不能訪問。
[0019]消費(fèi)者刪除節(jié)點(diǎn)時(shí),先要找到與當(dāng)前時(shí)間比對(duì)最近的節(jié)點(diǎn)的時(shí)間戳,獲取節(jié)點(diǎn)之后,修改索引值,然后再進(jìn)行堆化操作,在這個(gè)過程中同樣要保證無(wú)鎖堆的交換狀態(tài)和修改狀態(tài)的一致性,刪除節(jié)點(diǎn)的算法如圖2所示。該算法與插入算法不同的地方在于要比對(duì)與當(dāng)前時(shí)間最近的節(jié)點(diǎn),然后進(jìn)行堆化操作。
【主權(quán)項(xiàng)】
1.一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,其特征在于,包括以下步驟: (1)建立生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型;所述生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型包括采集部分和處理部分,采集部分和處理部分并行進(jìn)行; (2)建立數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程; (3)使用有序堆建立數(shù)據(jù)緩沖區(qū),數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳有序排放,數(shù)據(jù)緩沖區(qū)容量固定,數(shù)據(jù)節(jié)點(diǎn)在邏輯上是樹形結(jié)構(gòu); (4)數(shù)據(jù)生產(chǎn)者線程和測(cè)點(diǎn)數(shù)據(jù)消費(fèi)者線程對(duì)緩沖區(qū)進(jìn)行同步操作,操作完成后緩沖區(qū)恢復(fù)有序; (5)使用CAS原子操作實(shí)現(xiàn)對(duì)緩沖區(qū)的無(wú)鎖增加、刪除和排序,實(shí)現(xiàn)線程同步操作,避免兩組工作線程阻塞。
2.根據(jù)權(quán)利要求1所述的一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,其特征在于,所述步驟(2)中,生產(chǎn)者和消費(fèi)者可能是單一線程也可能是一組工作線程,兩個(gè)線程單獨(dú)工作互不影響。
3.根據(jù)權(quán)利要求1所述的一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,其特征在于,所述步驟(4)具體為:生產(chǎn)者采集數(shù)據(jù)存入數(shù)據(jù)緩沖區(qū),若緩沖區(qū)不滿,將生產(chǎn)者采集的數(shù)據(jù)直接放入緩沖區(qū)的末尾,并且對(duì)緩沖區(qū)中的數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)滿,生產(chǎn)者采集的數(shù)據(jù)與緩沖區(qū)中時(shí)間戳最舊的數(shù)據(jù)交換后按時(shí)間戳自動(dòng)排序;消費(fèi)者從數(shù)據(jù)緩沖區(qū)取數(shù)據(jù),若緩沖區(qū)不空,將緩沖區(qū)中時(shí)間戳最新的數(shù)據(jù)取出,并且對(duì)緩沖區(qū)中剩余數(shù)據(jù)按時(shí)間戳自動(dòng)排序;若緩沖區(qū)空,則等待生產(chǎn)者采集的數(shù)據(jù)。
【專利摘要】本發(fā)明公開了一種基于無(wú)鎖緩沖區(qū)的數(shù)據(jù)采集方法,該方法包括:使用面向?qū)ο蠓椒ǔ橄髷?shù)據(jù)邏輯,建立生產(chǎn)者-消費(fèi)者數(shù)據(jù)采集模型;使用多線程技術(shù),建立數(shù)據(jù)生產(chǎn)者線程和消費(fèi)者線程;使用有序堆作為多線程同步的數(shù)據(jù)緩沖區(qū);使用CAS原子操作構(gòu)建數(shù)據(jù)緩沖區(qū)數(shù)據(jù)讀寫的無(wú)鎖同步算法。本發(fā)明使用生產(chǎn)者-消費(fèi)者緩沖區(qū)實(shí)現(xiàn)有序的數(shù)據(jù)排列,并且能夠以無(wú)鎖的方式實(shí)現(xiàn)兩部分線程的同步訪問而不出現(xiàn)數(shù)據(jù)污染和沖突。
【IPC分類】G06F9-52
【公開號(hào)】CN104809027
【申請(qǐng)?zhí)枴緾N201510192246
【發(fā)明人】王友釗, 黃靜
【申請(qǐng)人】浙江大學(xué)
【公開日】2015年7月29日
【申請(qǐng)日】2015年4月21日