本發(fā)明涉及計(jì)算機(jī)多線程,原子操作,讀寫鎖。具體來說,在多線程環(huán)境下,利用原子操作,實(shí)現(xiàn)高效的讀寫鎖方法。
背景技術(shù):
在多線程環(huán)境下,有這樣一種場景(即一種單讀、單寫的場景),對于一段共享數(shù)據(jù)隊(duì)列,只有一個(gè)用戶做寫操作,同時(shí)也只有一個(gè)用戶做讀操作的情況下,如何提高線程讀寫鎖效率;常用的方法是利用操作系統(tǒng)提供的線程鎖,如圖1所示,這種方式功能強(qiáng)大,適應(yīng)性高,但在此場景效率低,因?yàn)榫€程鎖采用的是阻塞的方式,另外,線程鎖調(diào)用本身也有開銷,如果大量的調(diào)用加鎖/解鎖的話,開銷也比較大。
技術(shù)實(shí)現(xiàn)要素:
針對現(xiàn)有技術(shù)中存在的技術(shù)問題,本發(fā)明的目的是提供一種高效讀寫鎖的實(shí)現(xiàn)方法,本發(fā)明通過一種無需加鎖的方法,來實(shí)現(xiàn)2個(gè)線程(一個(gè)讀線程和一個(gè)寫線程)對一個(gè)共享數(shù)據(jù)隊(duì)列的訪問。
為了實(shí)現(xiàn)上述目的,本發(fā)明的解決方案是:
一種高效讀寫鎖的實(shí)現(xiàn)方法,其步驟為:
1)程序的主線程初始化共享數(shù)據(jù)隊(duì)列,為該共享數(shù)據(jù)隊(duì)列設(shè)置一寫線程和一讀線程,以及設(shè)置一整數(shù)變量M來保存該共享數(shù)據(jù)隊(duì)列最大長度,設(shè)置一變量K保存當(dāng)前該共享數(shù)據(jù)隊(duì)列中的數(shù)據(jù)個(gè)數(shù);
2)當(dāng)該程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行寫操作時(shí),該主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的寫線程,該寫線程做寫操作前,先檢查K,如果K<M,則把要寫的數(shù)據(jù)插入到該共享數(shù)據(jù)隊(duì)列的寫端,并且增加K的計(jì)數(shù)值;
3)當(dāng)該程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行讀操作時(shí),該主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的讀線程,該讀線程做讀操作前,檢查K,如果K>0,則從該共享數(shù)據(jù)隊(duì)列的讀端讀取一個(gè)元素,并且減少K的計(jì)數(shù)值。
進(jìn)一步的,所述步驟2)中,如果K大于或等于M,即該共享數(shù)據(jù)隊(duì)列已滿,則丟棄當(dāng)前要寫的數(shù)據(jù)。
進(jìn)一步的,所述步驟2)中,如果K大于或等于M,即該共享數(shù)據(jù)隊(duì)列已滿,則等待該共享數(shù)據(jù)隊(duì)列未滿時(shí),將當(dāng)前要寫的數(shù)據(jù)插入到該共享數(shù)據(jù)隊(duì)列的寫端,并且增加K的計(jì)數(shù)值。
進(jìn)一步的,所述步驟3)中,如果K=0,即該共享數(shù)據(jù)隊(duì)列為空,則采取等待或者輪詢的方式檢測該共享數(shù)據(jù)隊(duì)列中是否存在數(shù)據(jù),如果存在,則從該共享數(shù)據(jù)隊(duì)列的讀端讀取一個(gè)元素,并且減少K的計(jì)數(shù)值。
進(jìn)一步的,該共享數(shù)據(jù)隊(duì)列中的元素為寫入數(shù)據(jù)的指針。
本發(fā)明的主要內(nèi)容包括:
a.程序的主線程初始化共享數(shù)據(jù)隊(duì)列,用一個(gè)整數(shù)變量M來保存該共享數(shù)據(jù)隊(duì)列最大長度,K保存當(dāng)前該共享數(shù)據(jù)隊(duì)列中的數(shù)據(jù)個(gè)數(shù)。
b.當(dāng)程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行寫操作時(shí),主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的寫線程,該寫線程做寫操作前,先檢查K,如果K<M,運(yùn)行push操作,即把要寫的數(shù)據(jù)插入到該共享數(shù)據(jù)隊(duì)列的寫端,并且K++,如果K>=M,說明該共享數(shù)據(jù)隊(duì)列已滿,那么可以采取丟棄或者等待的方式。
c.當(dāng)程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行讀操作時(shí),主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的讀線程,該讀線程做讀操作前,檢查K,如果K>0,執(zhí)行pop操作,即從該共享數(shù)據(jù)隊(duì)列的讀端讀取一個(gè)元素,K--,如果K=0,說明該共享數(shù)據(jù)隊(duì)列為空,那么可以采取等待或者輪詢的方式。
與現(xiàn)有技術(shù)相比,本發(fā)明的優(yōu)點(diǎn)和積極效果為:
在本發(fā)明中,在單讀單寫的情況下,通過整數(shù)加減操作,對共享數(shù)據(jù)隊(duì)列中的元素進(jìn)行訪問。相對于采用線程鎖,本發(fā)明大大提高了讀寫效率,消除了由于頻繁的調(diào)用線程鎖而產(chǎn)生的開銷。
附圖說明
圖1為傳統(tǒng)讀寫鎖的流程圖;
圖2為本發(fā)明方法的流程圖。
具體實(shí)現(xiàn)方式
本發(fā)明流程如圖2所示,具體如下:
(1)程序啟動后,由該程序的主線程來初始化共享數(shù)據(jù)隊(duì)列并創(chuàng)建讀線程和寫線程,該共享數(shù)據(jù)隊(duì)列中的元素為寫入數(shù)據(jù)的指針,共享數(shù)據(jù)隊(duì)列最大長度為M,共享數(shù)據(jù)隊(duì)列當(dāng)前元素個(gè)數(shù)為K,K=0。
(2)當(dāng)程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行寫操作時(shí),主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的寫線程,該寫線程操作的時(shí)候,檢查K,如果K<M,寫線程執(zhí)行隊(duì)列的push操作,即把要寫的數(shù)據(jù)插入到共享數(shù)據(jù)隊(duì)列的寫端,并執(zhí)行K++;如果K>=M,返回NULL,表示共享數(shù)據(jù)隊(duì)列已經(jīng)滿了,本次寫入失敗,可以根據(jù)自身需要進(jìn)行等待或者輪詢。
(3)當(dāng)程序需要對該共享數(shù)據(jù)隊(duì)列進(jìn)行讀操作時(shí),主線程調(diào)用該共享數(shù)據(jù)隊(duì)列的讀線程,該讀線程操作的時(shí)候,檢查K,如果K>0,讀線程執(zhí)行隊(duì)列的pop操作,即從共享數(shù)據(jù)隊(duì)列的讀端讀取一個(gè)元素,并執(zhí)行K--;如果K<=0,返回NULL,表示共享數(shù)據(jù)隊(duì)列已經(jīng)空了,即當(dāng)前無數(shù)據(jù)可讀,可以根據(jù)自身需要進(jìn)行等待或者輪詢。
實(shí)施例
假如共享數(shù)據(jù)隊(duì)列的初始最大長度為M=10,共享數(shù)據(jù)隊(duì)列當(dāng)前的元素個(gè)數(shù)K=0
例1:寫入
檢查K=0<M=10,所以可以執(zhí)行寫入,并且執(zhí)行K++,此時(shí)K=1
例2:讀取
檢查K=1>0,執(zhí)行讀取操作,并且執(zhí)行K--,此時(shí)K=0。