一種數(shù)據(jù)傳輸裝置和方法
【專利摘要】本發(fā)明公開(kāi)了一種數(shù)據(jù)傳輸裝置和方法,其中數(shù)據(jù)傳輸裝置包括:數(shù)據(jù)存儲(chǔ)器,適于以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù),循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引,循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng)一個(gè)序列號(hào);寫(xiě)接口,適于接收生產(chǎn)者線程的寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),包括讀取頭索引并將其賦值給第一索引,通過(guò)判斷第一索引指向的元素的序列號(hào)與第一索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作;讀接口,適于接收消費(fèi)者線程的讀取指令從循環(huán)隊(duì)列讀取數(shù)據(jù),包括讀取尾索引并將其賦值給第二索引,通過(guò)判斷第二索引指向的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操作;其中,頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。
【專利說(shuō)明】
_種數(shù)據(jù)傳輸裝置和方法
技術(shù)領(lǐng)域
[0001 ]本發(fā)明涉及數(shù)據(jù)通信領(lǐng)域,特別涉及一種數(shù)據(jù)傳輸裝置和方法。
【背景技術(shù)】
[0002] 隨著計(jì)算機(jī)應(yīng)用的日益廣泛和深入,與數(shù)據(jù)交互和傳輸相關(guān)的技術(shù)也不斷發(fā)展和 進(jìn)步。在數(shù)據(jù)通信的過(guò)程中,當(dāng)使用多線程并發(fā)處理數(shù)據(jù)時(shí),如果直接處理,需要在并發(fā)請(qǐng) 求的過(guò)程中使用互斥鎖來(lái)保持?jǐn)?shù)據(jù)的一致性。尤其在涉及到大量的請(qǐng)求時(shí),使用原有的互 斥鎖機(jī)制難以保證這些請(qǐng)求之間的有序并發(fā)處理,時(shí)間消耗較大。以多線程并發(fā)對(duì)同一文 件記錄日志為例,如果直接寫(xiě)入文件,由于同一進(jìn)程共用文件表,必須對(duì)寫(xiě)入操作加鎖,此 時(shí)并發(fā)寫(xiě)入調(diào)用在邏輯上轉(zhuǎn)化為實(shí)際的串行文件寫(xiě)入,而線程同步本身也會(huì)消耗時(shí)間,導(dǎo) 致在并發(fā)較大時(shí)線程同步的時(shí)間消耗甚至大于日志寫(xiě)入本身的時(shí)間消耗。
[0003] 然而,即使通過(guò)隊(duì)列作為媒介,用戶線程作為生產(chǎn)者構(gòu)造數(shù)據(jù)處理任務(wù)并向隊(duì)列 寫(xiě)入,線程池作為消費(fèi)者從隊(duì)列讀取數(shù)據(jù)處理任務(wù)并執(zhí)行,利用隊(duì)列對(duì)任務(wù)進(jìn)行傳輸來(lái)實(shí) 現(xiàn)異步數(shù)據(jù)處理,但多線程下的隊(duì)列操作仍需要加鎖,時(shí)間上的過(guò)多消耗難以消除。
【發(fā)明內(nèi)容】
[0004] 為此,本發(fā)明提供一種數(shù)據(jù)傳輸?shù)姆桨福粤D解決或者至少緩解上面存在的問(wèn) 題。
[0005] 根據(jù)本發(fā)明的一個(gè)方面,提供一種數(shù)據(jù)傳輸裝置,包括:數(shù)據(jù)存儲(chǔ)器,適于以循環(huán) 隊(duì)列存儲(chǔ)數(shù)據(jù),循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引,循環(huán)隊(duì)列中的每個(gè)元素對(duì) 應(yīng)一個(gè)序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo);寫(xiě)接口,適于接收一個(gè)或多個(gè)生產(chǎn)者 線程的寫(xiě)入指令,根據(jù)寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù)包括讀取頭索 引并將其賦值給第一索引,通過(guò)判斷第一索引指向的元素的序列號(hào)與第一索引的大小,執(zhí) 行相應(yīng)的數(shù)據(jù)寫(xiě)入操作;讀接口,適于接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,根據(jù)讀取指 令從循環(huán)隊(duì)列讀取數(shù)據(jù),從循環(huán)隊(duì)列讀取數(shù)據(jù)包括讀取尾索引并將其賦值給第二索引,通 過(guò)判斷第二索引指向的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操作;其 中,頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。
[0006] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,寫(xiě)接口進(jìn)一步適于:當(dāng)序列號(hào)等于第一 索引時(shí),頭索引增加1,將待寫(xiě)入數(shù)據(jù)寫(xiě)入第一索引指向的元素中,序列號(hào)增加1。
[0007] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,寫(xiě)接口進(jìn)一步適于:當(dāng)序列號(hào)大于第一 索引時(shí),重新向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重寫(xiě)次數(shù)時(shí),判斷數(shù)據(jù)寫(xiě)入 失敗。
[0008] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,寫(xiě)接口進(jìn)一步適于:當(dāng)序列號(hào)小于第一 索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。
[0009] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,讀接口進(jìn)一步適于:當(dāng)序列號(hào)減1的值 等于第二索引時(shí),尾索引增加1,將待讀取數(shù)據(jù)從第二索引指向的元素中讀取出來(lái),序列號(hào) 增加數(shù)組長(zhǎng)度再減去1。
[0010] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,讀接口進(jìn)一步適于:當(dāng)序列號(hào)減1的值 大于第二索引時(shí),重新從循環(huán)隊(duì)列讀取數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重讀次數(shù)時(shí),判斷 數(shù)據(jù)讀取失敗。
[0011] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,讀接口進(jìn)一步適于:當(dāng)序列號(hào)減1的值 小于第二索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失敗。
[0012] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,數(shù)據(jù)包括日志任務(wù)。
[0013] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,生產(chǎn)者線程在日志任務(wù)寫(xiě)入失敗時(shí),執(zhí) 行日志任務(wù),生成日志文件。
[0014] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,消費(fèi)者線程在日志任務(wù)讀取成功時(shí),執(zhí) 行日志任務(wù),生成日志文件。
[0015] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸裝置中,讀接口進(jìn)一步適于:當(dāng)日志任務(wù)讀取失 敗時(shí),等待預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。
[0016] 根據(jù)本發(fā)明的又一個(gè)方面,提供一種數(shù)據(jù)傳輸方法,適于對(duì)以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù) 的數(shù)據(jù)存儲(chǔ)器進(jìn)行寫(xiě)入和讀取操作,其中循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引, 循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng)一個(gè)序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo),方法包括: 接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令,根據(jù)寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),向循環(huán)隊(duì)列 寫(xiě)入數(shù)據(jù)包括讀取頭索引并將其賦值給第一索引,通過(guò)判斷第一索引指向的元素的序列號(hào) 與第一索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作;接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,根 據(jù)讀取指令從循環(huán)隊(duì)列讀取數(shù)據(jù),從循環(huán)隊(duì)列讀取數(shù)據(jù)包括讀取尾索引并將其賦值給第二 索引,通過(guò)判斷第二索引指向的元素的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù) 讀取操作;其中,頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。
[0017] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)寫(xiě)入操作包括:如果序列號(hào)等于第 一索引,則頭索引增加1,將待寫(xiě)入數(shù)據(jù)寫(xiě)入第一索引指向的元素中,序列號(hào)增加1。
[0018] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)寫(xiě)入操作包括:如果序列號(hào)大于第 一索引,則重新向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),如果重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重寫(xiě)次數(shù),則判斷數(shù)據(jù) 寫(xiě)入失敗。
[0019] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)寫(xiě)入操作包括:如果序列號(hào)小于第 一索引,則判斷當(dāng)前循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。
[0020] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)讀取操作包括:如果序列號(hào)減1的 值等于第二索引,則尾索引增加1,將待讀取數(shù)據(jù)從第二索引指向的元素中讀取出來(lái),序列 號(hào)增加數(shù)組長(zhǎng)度再減去1。
[0021 ]可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)讀取操作包括:如果序列號(hào)減1的 值大于第二索引,則重新從循環(huán)隊(duì)列讀取數(shù)據(jù),如果重寫(xiě)次數(shù)達(dá)到最大重讀次數(shù),則判斷數(shù) 據(jù)寫(xiě)入失敗。
[0022] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)讀取操作包括:如果序列號(hào)減1的 值小于第二索引,則判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失敗。
[0023] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)包括日志任務(wù)。
[0024] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,還包括:如果日志任務(wù)寫(xiě)入失敗,則生 產(chǎn)者線程執(zhí)行日志任務(wù),生成日志文件。
[0025] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,還包括:如果日志任務(wù)讀取成功,則消 費(fèi)者線程執(zhí)行日志任務(wù),生成日志文件。
[0026] 可選地,在根據(jù)本發(fā)明的數(shù)據(jù)傳輸方法中,數(shù)據(jù)讀取操作還包括:如果日志任務(wù)讀 取失敗,則等待預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。
[0027] 根據(jù)本發(fā)明的數(shù)據(jù)傳輸?shù)募夹g(shù)方案,對(duì)以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)存儲(chǔ)器進(jìn)行寫(xiě) 入和讀取操作,每個(gè)隊(duì)列元素具有一個(gè)序列號(hào),接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令來(lái) 向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),同時(shí)接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令來(lái)從循環(huán)隊(duì)列讀取數(shù) 據(jù),生產(chǎn)者線程和消費(fèi)者線程以一個(gè)無(wú)鎖循環(huán)隊(duì)列為媒介進(jìn)行數(shù)據(jù)傳輸,借助隊(duì)列元素上 的序列號(hào),在入/出隊(duì)時(shí)可無(wú)鎖的實(shí)現(xiàn)"隊(duì)滿/空"、"寫(xiě)/讀成功"、"寫(xiě)/讀沖突"三種狀態(tài)的判 斷,而且通過(guò)對(duì)序列號(hào)和隊(duì)列長(zhǎng)度減1的值進(jìn)行"與"運(yùn)算,相當(dāng)于將循環(huán)隊(duì)列展開(kāi)為無(wú)數(shù)個(gè) 先入先出隊(duì)列,實(shí)現(xiàn)隊(duì)列的循環(huán)使用即循環(huán)隊(duì)列,并支持多線程在不加互斥鎖的情況下同 時(shí)進(jìn)行數(shù)據(jù)寫(xiě)入/讀取操作,消除了因加鎖機(jī)制造成的阻塞等待,降低了數(shù)據(jù)處理的平均響 應(yīng)時(shí)延。
【附圖說(shuō)明】
[0028] 為了實(shí)現(xiàn)上述以及相關(guān)目的,本文結(jié)合下面的描述和附圖來(lái)描述某些說(shuō)明性方 面,這些方面指示了可以實(shí)踐本文所公開(kāi)的原理的各種方式,并且所有方面及其等效方面 旨在落入所要求保護(hù)的主題的范圍內(nèi)。通過(guò)結(jié)合附圖閱讀下面的詳細(xì)描述,本公開(kāi)的上述 以及其它目的、特征和優(yōu)勢(shì)將變得更加明顯。遍及本公開(kāi),相同的附圖標(biāo)記通常指代相同的 部件或元素。
[0029] 圖1示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)存取裝置100的示意圖;
[0030]圖2(a)_(e)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的以數(shù)組結(jié)構(gòu)實(shí)現(xiàn)的循環(huán)隊(duì)列進(jìn)行 數(shù)據(jù)傳輸過(guò)程中隊(duì)列狀態(tài)的示意圖;
[0031] 圖3示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)傳輸方法中向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù)的方 法300的流程圖;以及
[0032] 圖4示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)傳輸方法中從循環(huán)隊(duì)列讀取數(shù)據(jù)的方 法400的流程圖。
【具體實(shí)施方式】
[0033] 下面將參照附圖更詳細(xì)地描述本公開(kāi)的示例性實(shí)施例。雖然附圖中顯示了本公開(kāi) 的示例性實(shí)施例,然而應(yīng)當(dāng)理解,可以以各種形式實(shí)現(xiàn)本公開(kāi)而不應(yīng)被這里闡述的實(shí)施例 所限制。相反,提供這些實(shí)施例是為了能夠更透徹地理解本公開(kāi),并且能夠?qū)⒈竟_(kāi)的范圍 完整的傳達(dá)給本領(lǐng)域的技術(shù)人員。
[0034] 圖1示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)存取裝置100的示意圖。如圖1所述,該 裝置包括數(shù)據(jù)存儲(chǔ)器110、寫(xiě)接口 120和讀接口 130。其中,數(shù)據(jù)存儲(chǔ)器110適于以循環(huán)隊(duì)列存 儲(chǔ)數(shù)據(jù),循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引,循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng)一個(gè) 序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo)。其中,頭索引、尾索引和序列號(hào)均是原子對(duì) 象。采用原子對(duì)象的意義在于,可以保證在賦值操作之前的所有內(nèi)存操作不會(huì)被重排序到 賦值操作之后,即避免了處理同一元素時(shí)因?yàn)橹噶钪嘏哦斐僧惓=Y(jié)果。在本實(shí)施例中,實(shí) 現(xiàn)循環(huán)隊(duì)列的數(shù)組以buf f er表示,數(shù)組長(zhǎng)度以1 en表示,其值為8,包括buf f er [ 0 ]至buf fer [7]的8個(gè)元素,頭索引以head表示,尾索引以tail表示,head和tail在初始狀態(tài)均指向循環(huán) 隊(duì)列的第一個(gè)元素 buf fer [0],循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng)一個(gè)序列號(hào)seq,buf fer [0]至 buffer[7]的序列號(hào)初始化后依次為0、1、2、3、4、5、6和7。
[0035] 圖2(a)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的以數(shù)組結(jié)構(gòu)實(shí)現(xiàn)的循環(huán)隊(duì)列初始狀態(tài) 的示意圖。如圖2所示,初始化后,頭索引head和尾索引tail均指向第一個(gè)元素 buffer[0], 其中0至7分別表示對(duì)應(yīng)元素的序列號(hào)seq。
[0036] 寫(xiě)接口 120適于接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令,每接收到一條寫(xiě)入指令, 則根據(jù)該寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),包括讀取頭索引并將其賦值給第一索引,通過(guò)判 斷第一索引指向的元素的序列號(hào)與第一索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作,其中,第一 索引是原子對(duì)象。寫(xiě)接口 120進(jìn)一步適于當(dāng)序列號(hào)等于第一索引時(shí),頭索引增加1,將待寫(xiě)入 數(shù)據(jù)寫(xiě)入第一索引指向的元素中,序列號(hào)增加1;當(dāng)序列號(hào)大于第一索引時(shí),重新向循環(huán)隊(duì) 列寫(xiě)入數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重寫(xiě)次數(shù)時(shí),判斷數(shù)據(jù)寫(xiě)入失?。划?dāng)序列號(hào)小于第 一索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。在本實(shí)施例中,對(duì)如圖2(a)所示的循環(huán) 隊(duì)列執(zhí)行數(shù)據(jù)寫(xiě)入操作。第一索引以P〇sl表示,讀取head的值并將其賦值給posl,當(dāng)前head 的值為0,則口〇81的值為0。而口〇81指向的元素為131^€61'|^〇81&(1611-1)],其中口〇81&(1611-1) 表示將posl和len-Ι的值轉(zhuǎn)化為二進(jìn)制后進(jìn)行與操作,得到的結(jié)果轉(zhuǎn)化為十進(jìn)制后作為數(shù) 組buf fer的下標(biāo)。此時(shí),pos 1的值為0,轉(zhuǎn)換成二進(jìn)制表示為0000,len-Ι的值為7,轉(zhuǎn)化成二 進(jìn)制表示為0111,則0000&0111得到的值為〇〇〇〇,轉(zhuǎn)化為十進(jìn)制后為〇,得到當(dāng)前posl指向的 元素為buf fer [0],其對(duì)應(yīng)的seq為0。由于buf fer [0]對(duì)應(yīng)的seq與posl相等,因此將head的 值增加1,并將待寫(xiě)入數(shù)據(jù)寫(xiě)入posl指向的元素 buf fer [0]中,而buf fer [0]對(duì)應(yīng)的seq也增 加1〇
[0037] 由于在進(jìn)行數(shù)據(jù)寫(xiě)入操作時(shí),存在多個(gè)生產(chǎn)者線程同時(shí)寫(xiě)入的情況,此時(shí)各生產(chǎn) 者線程需要對(duì)循環(huán)隊(duì)列中的元素進(jìn)行搶占。實(shí)際上,在對(duì)head進(jìn)行加1的操作時(shí),是使用 try_compare(head,posl,posl+l)函數(shù)來(lái)進(jìn)行處理的。其中,try_compare(head,posl,posl + 1)函數(shù)是原子比較交換函數(shù)。當(dāng)執(zhí)行該函數(shù)時(shí),如果head = posl,則說(shuō)明在執(zhí)行函數(shù)之前 沒(méi)有進(jìn)行數(shù)據(jù)寫(xiě)入操作,則將P〇s 1+1的值賦值給head,pos 1的值保持不變,實(shí)現(xiàn)了對(duì)head加 1的操作。各生產(chǎn)者線程均嘗試執(zhí)行1^7_(3011^^代(1163(14〇814〇81 + 1)函數(shù)來(lái)對(duì)1163(1進(jìn)行加 1操作,但只可能存在一個(gè)生產(chǎn)者線程成功,該成功使得head增加1的生產(chǎn)者線程搶占到 buff er[0]后寫(xiě)入數(shù)據(jù)。圖2(b)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的成功寫(xiě)入一個(gè)數(shù)據(jù)后的 循環(huán)隊(duì)列的隊(duì)列狀態(tài)示意圖。如圖2(b)所示,此時(shí)head的值為1,指向的元素為buffer[l], buff er[0]對(duì)應(yīng)的seq的值為1。
[0038] 在上述各生產(chǎn)者線程搶占元素 bUffer[0]的過(guò)程中,對(duì)搶占失敗的生產(chǎn)者線程而 言,此時(shí)的buff er[0]對(duì)應(yīng)的序列號(hào)seq的值為1,而搶占失敗的生產(chǎn)者線程尚未重讀head的 值來(lái)重新向循環(huán)隊(duì)列中寫(xiě)入數(shù)據(jù),使得posl的值并未更新而仍然為0,由于 Seq>p〇Sl,因此 上述失敗的生產(chǎn)者線程重新讀取head的值來(lái)繼續(xù)嘗試寫(xiě)入數(shù)據(jù),并重寫(xiě)次數(shù)增加1。一般預(yù) 設(shè)最大重寫(xiě)次數(shù)為20次,如果生產(chǎn)者線程對(duì)數(shù)據(jù)的重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重寫(xiě)次數(shù),則 判斷數(shù)據(jù)寫(xiě)入失敗。
[0039] 圖2(c)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的循環(huán)隊(duì)列已滿的隊(duì)列狀態(tài)示意圖。如圖 2 (c)所示,當(dāng)前循環(huán)隊(duì)列已滿,此時(shí)元素 buffer [0]至buffer [7]對(duì)應(yīng)的序列號(hào)seq分別為1、 2、3、4、5、6、7和8。而在生產(chǎn)者線程搶占131^€61'[7]時(shí),1:巧_(3〇11^^代(1163(1,口〇81,口〇81+1)函 數(shù)對(duì)head執(zhí)行了加1的操作,使得head的值更新為8。而此時(shí)搶占 buffer [7]失敗的生產(chǎn)者線 程重新嘗試寫(xiě)入數(shù)據(jù),讀取head的值并賦值給posl,而posl指向的元素 buffer[posl&(len-1)]為131^€61'[1000&0111],即為131^€61'[0]。頭索引1163(1重新指向了循環(huán)隊(duì)列的第一個(gè)元 素,實(shí)現(xiàn)了邏輯上的循環(huán)結(jié)構(gòu)。判斷buffer [0]對(duì)應(yīng)的seq與posl的大小,此時(shí),seq的值為1, posl的值為8,則Seq〈p〇sl,判斷循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。
[0040] 讀接口 130適于接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,每接收到一條讀取指令, 則根據(jù)讀取指令從循環(huán)隊(duì)列讀取數(shù)據(jù),包括讀取尾索引并將其賦值給第二索引,通過(guò)判斷 第二索引指向的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操作,其中,第二 索引為原子對(duì)象。讀接口 130進(jìn)一步適于當(dāng)序列號(hào)減1的值等于第二索引時(shí),尾索引增加1, 將待讀取數(shù)據(jù)從第二索引指向的元素中讀取出來(lái),序列號(hào)增加數(shù)組長(zhǎng)度再減去1;當(dāng)序列號(hào) 減1的值大于第二索引時(shí),重新從循環(huán)隊(duì)列讀取數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重讀次數(shù) 時(shí),判斷數(shù)據(jù)讀取失?。划?dāng)序列號(hào)減1的值小于第二索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀 取失敗。在本實(shí)施例中,對(duì)如圖2(c)所示的循環(huán)隊(duì)列執(zhí)行數(shù)據(jù)讀取操作。第二索引以pos2表 示,讀取tail的值并將其賦值給pos2,當(dāng)前tail的值為0,則pos2的值為0。而pos2指向的元 素為131^€61'|^082&(1611-1],其中口082&(1611-1)表示將口082和1611-1的值轉(zhuǎn)化為二進(jìn)制后進(jìn) 行與操作,得到的結(jié)果轉(zhuǎn)化為十進(jìn)制后作為數(shù)組buffer的下標(biāo)。此時(shí),pos2的值為0,轉(zhuǎn)換成 二進(jìn)制表示為〇〇〇〇,len-l的值為7,轉(zhuǎn)化成二進(jìn)制表示為0111,則0000&0111得到的值為 〇〇〇〇,轉(zhuǎn)化為十進(jìn)制后為0,得到當(dāng)前p〇s2指向的元素為buffer[0],其對(duì)應(yīng)的seq為1。由于 buffer[0]對(duì)應(yīng)的seq減1的值與pos2相等,因此將tail的值增加1,并將待讀取數(shù)據(jù)從pos2 指向的元素 buffer [0]中讀取出來(lái),而buffer [0]對(duì)應(yīng)的seq增加 len再減去1。
[0041] 由于在進(jìn)行數(shù)據(jù)讀取操作時(shí),存在多個(gè)消費(fèi)者線程同時(shí)讀取的情況,此時(shí)各消費(fèi) 者線程需要對(duì)循環(huán)隊(duì)列中的元素進(jìn)行搶占。實(shí)際上,在對(duì)tail進(jìn)行加1的操作時(shí),是使用 try_compare (tai 1,pos2,pos2+l)函數(shù)來(lái)進(jìn)行處理的。其中,try_compare (tai 1,pos2,pos2 + 1)函數(shù)是原子比較交換函數(shù)。當(dāng)執(zhí)行該函數(shù)時(shí),如果tail =pos2,則說(shuō)明在執(zhí)行函數(shù)之前 沒(méi)有進(jìn)行數(shù)據(jù)讀取操作,則將P〇s2+l的值賦值給tail,pos2的值保持不變,實(shí)現(xiàn)了對(duì)tail加 1的操作。各消費(fèi)者線程均嘗試執(zhí)行1^7_〇011^^代(丨3;[14082 4082+1)函數(shù)來(lái)對(duì)丨3;[1進(jìn)行加 1操作,但只可能存在一個(gè)消費(fèi)者線程成功,該成功使得tail增加1的消費(fèi)者線程搶占到 buff er[0]后讀取數(shù)據(jù)。圖2(d)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的成功讀取一個(gè)數(shù)據(jù)后的 循環(huán)隊(duì)列的隊(duì)列狀態(tài)示意圖。如圖2(d)所示,此時(shí)tail的值為1,指向的元素為buffer[l], buff er[0]對(duì)應(yīng)的seq的值為8。
[0042] 在上述各消費(fèi)者線程搶占元素 bUffer[0]的過(guò)程中,對(duì)搶占失敗的消費(fèi)者線程而 言,此時(shí)的buff er[0]對(duì)應(yīng)的序列號(hào)seq的值為8,而搶占失敗的消費(fèi)者線程尚未重讀tail的 值來(lái)重新從循環(huán)隊(duì)列中讀取數(shù)據(jù),使得P〇s2的值并未更新而仍然為0,由于 Seq-l>p〇s2,因 此上述失敗的消費(fèi)者線程重新讀取tail的值來(lái)繼續(xù)嘗試讀取數(shù)據(jù),并將重讀次數(shù)增加1。一 般預(yù)設(shè)最大重讀次數(shù)為20次,如果消費(fèi)者線程對(duì)數(shù)據(jù)的重讀次數(shù)達(dá)到預(yù)設(shè)的最大重讀次 數(shù),則判斷數(shù)據(jù)讀取失敗。
[0043] 圖2(e)示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的循環(huán)隊(duì)列已空的隊(duì)列狀態(tài)示意圖。如圖 2 (e)所示,當(dāng)前循環(huán)隊(duì)列已空,此時(shí)元素 buffer [0]至buffer [7]對(duì)應(yīng)的序列號(hào)seq分別為8、 9、10、11、12、13、14和15。而在消費(fèi)者線程搶占 bufTer[7]時(shí),try_compare(tail,pos2,pos2 + 1)函數(shù)對(duì)tail執(zhí)行了加1的操作,使得tail的值更新為8。而此時(shí)搶占 buffer [7]失敗的消 費(fèi)者線程重新嘗試讀取數(shù)據(jù),讀取tail的值并賦值給pos2,而pos2指向的元素 buffer [pos2&(len_l)]為buffer[ 1000&0111],即為buffer[0]。尾索引 tail重新指向了循環(huán)隊(duì)列 的第一個(gè)元素,實(shí)現(xiàn)了邏輯上的循環(huán)結(jié)構(gòu)。判斷buffer[0]對(duì)應(yīng)的seq減1的值與pos2的大 小,此時(shí),seq的值為8,pos2的值為8,則seq_l〈pos2,判斷循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失敗。
[0044] 至此,循環(huán)隊(duì)列中的元素中均寫(xiě)入和讀取數(shù)據(jù)一次,頭索引head和尾索引tail的 值均為8,且均指向循環(huán)隊(duì)列的第一個(gè)元素 bUffer[0],完成了一次回繞,實(shí)現(xiàn)了無(wú)鎖循環(huán)隊(duì) 列。
[0045] 在本發(fā)明的實(shí)施例中,傳輸?shù)臄?shù)據(jù)可以是日志任務(wù)。當(dāng)生產(chǎn)者線程在日志任務(wù)寫(xiě) 入失敗時(shí),直接調(diào)用日志寫(xiě)入API,執(zhí)行日志寫(xiě)入函數(shù)將日志數(shù)據(jù)寫(xiě)入文件,以生成日志文 件。當(dāng)消費(fèi)者線程在日志任務(wù)讀取成功時(shí),消費(fèi)者線程調(diào)用日志寫(xiě)入函數(shù)執(zhí)行寫(xiě)入操作,生 成日志文件。其中,考慮到日志這一特殊的應(yīng)用場(chǎng)景,多線程并發(fā)執(zhí)行日志任務(wù),即并發(fā)寫(xiě) 入日志的實(shí)際性能低于單線程串行寫(xiě)入,因此可以只啟用單個(gè)消費(fèi)者線程。而當(dāng)日志任務(wù) 讀取失敗時(shí),讀接口進(jìn)一步適于等待預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。
[0046] 為驗(yàn)證本裝置100的效果,對(duì)百萬(wàn)行日志的生成進(jìn)行測(cè)試,從兩個(gè)方面觀察時(shí)間上 的消耗。表1示出了百萬(wàn)行日志生成測(cè)試中不同日志大小下的時(shí)間消耗對(duì)比。
[0048]表 1
[0049] 如表1所示,當(dāng)日志大小為5 0 0 B時(shí),接口調(diào)用時(shí)間為17 4 0 m s,實(shí)際寫(xiě)入時(shí)間為 14077ms,線程工作時(shí)間為13703毫秒;當(dāng)日志大小為2KB時(shí),接口調(diào)用時(shí)間為3535ms,實(shí)際寫(xiě) 入時(shí)間為16501ms,線程工作時(shí)間為16062ms。兩者相比發(fā)現(xiàn),當(dāng)日志大小從500B增大到2KB 時(shí),時(shí)間上的消耗并沒(méi)有快速增長(zhǎng),這一現(xiàn)象在實(shí)際寫(xiě)入時(shí)間和線程工作時(shí)間上表現(xiàn)得更 明顯。表2示出了百萬(wàn)行日志生成測(cè)試中異步寫(xiě)入和同步寫(xiě)入的時(shí)間消耗對(duì)比。
[0050]
[0051] 表 2
[0052] 如表2所示,當(dāng)存在10個(gè)用戶線程進(jìn)行異步寫(xiě)入時(shí),接口調(diào)用時(shí)間為2121ms,全部 寫(xiě)入時(shí)間為21435ms,線程工作時(shí)間為20824ms,總計(jì)44380ms,而10個(gè)用戶線程進(jìn)行同步寫(xiě) 入時(shí)的時(shí)間總計(jì)為48400ms。相比較之下發(fā)現(xiàn),異步寫(xiě)入的時(shí)間消耗小于同步寫(xiě)入,說(shuō)明本 發(fā)明的技術(shù)方案有助于降低時(shí)間消耗。
[0053] 根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)傳輸方法,適于對(duì)以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)存 儲(chǔ)器進(jìn)行寫(xiě)入和讀取操作,其中循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引,循環(huán)隊(duì)列 中的每個(gè)元素對(duì)應(yīng)一個(gè)序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo),方法包括:接收一個(gè) 或多個(gè)生產(chǎn)者線程的寫(xiě)入指令,根據(jù)寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù) 包括讀取頭索引并將其賦值給第一索引,通過(guò)判斷第一索引指向的元素的序列號(hào)與第一索 引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作;接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,根據(jù)讀取指 令從循環(huán)隊(duì)列讀取數(shù)據(jù),從循環(huán)隊(duì)列讀取數(shù)據(jù)包括讀取尾索引并將其賦值給第二索引,通 過(guò)判斷第二索引指向的元素的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操 作;其中,頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。
[0054] 圖3示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)傳輸方法中向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù)的方 法300的流程圖。如圖3所示,在步驟S310中,讀取頭索引并將其賦值給第一索引。隨后進(jìn)入 步驟S320,判斷第一索引指向的元素的序列號(hào)與第一索引的大小。如果第一索引指向的元 素的序列號(hào)等于第一索引,則執(zhí)行步驟S331,將頭索引增加1,將待寫(xiě)入數(shù)據(jù)寫(xiě)入第一索引 指向的元素中,并將序列號(hào)增加1;如果第一索引指向的元素的序列號(hào)大于第一索引,則執(zhí) 行步驟S332,重新向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),如果重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最大重寫(xiě)次數(shù),則判斷數(shù) 據(jù)寫(xiě)入失敗;如果第一索引指向的元素的序列號(hào)小于第一索引,則執(zhí)行步驟S333,判斷當(dāng)前 循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。
[0055] 圖4示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的數(shù)據(jù)傳輸方法中從循環(huán)隊(duì)列讀取數(shù)據(jù)的方 法400的流程圖。如圖4所示,在步驟S410中,讀取尾索引并將其賦值給第二索引。隨后進(jìn)入 步驟S420,判斷第二索引指向的元素的序列號(hào)與第二索引的大小。如果第二索引指向的元 素的序列號(hào)減1的值等于第二索引,則執(zhí)行步驟S431,將尾索引增加1,將待讀取數(shù)據(jù)從第二 索引指向的元素中讀取出來(lái),并將序列號(hào)增加數(shù)組長(zhǎng)度再減去1;如果第二索引指向的元素 的序列號(hào)減1的值大于第二索引,則執(zhí)行步驟S432,重新從循環(huán)隊(duì)列讀取數(shù)據(jù),如果重寫(xiě)次 數(shù)達(dá)到最大重讀次數(shù),則判斷數(shù)據(jù)寫(xiě)入失敗;如果第二索引指向的元素的序列號(hào)減1的值小 于第二索引,則執(zhí)行步驟S433,判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失敗。
[0056] 在本發(fā)明的實(shí)施例中,傳輸?shù)臄?shù)據(jù)可以是日志任務(wù)。如果日志任務(wù)寫(xiě)入失敗,則生 產(chǎn)者線程執(zhí)行日志任務(wù),生成日志文件。如果日志任務(wù)讀取成功,則消費(fèi)者線程執(zhí)行日志任 務(wù),生成日志文件。從循環(huán)隊(duì)列讀取數(shù)據(jù)的方法400還包括如果日志任務(wù)讀取失敗,則等待 預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。
[0057] 關(guān)于數(shù)據(jù)傳輸方法的具體步驟以及實(shí)施例,在基于圖1及圖2(a)_(e)的描述中已 經(jīng)詳細(xì)公開(kāi),此處不再贅述。
[0058] 根據(jù)本發(fā)明的數(shù)據(jù)傳輸?shù)募夹g(shù)方案,對(duì)循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)存儲(chǔ)器進(jìn)行寫(xiě)入 和讀取操作,接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令來(lái)向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),同時(shí)接收一 個(gè)或多個(gè)消費(fèi)者線程的讀取指令來(lái)從循環(huán)隊(duì)列讀取數(shù)據(jù),生產(chǎn)者線程和消費(fèi)者線程以一個(gè) 無(wú)鎖循環(huán)隊(duì)列為媒介進(jìn)行數(shù)據(jù)傳輸,支持多線程在不加互斥鎖的情況下同時(shí)進(jìn)行數(shù)據(jù)寫(xiě) 入/讀取操作,降低了因加鎖及解鎖帶來(lái)的時(shí)間消耗,進(jìn)一步提升了異步處理數(shù)據(jù)的能力。 [0059] A10.如A8所述的裝置,其中:
[0060]所述消費(fèi)者線程在所述日志任務(wù)讀取成功時(shí),執(zhí)行日志任務(wù),生成日志文件。
[0061 ] A11.如A8所述的裝置,所述讀接口進(jìn)一步適于:
[0062]當(dāng)所述日志任務(wù)讀取失敗時(shí),等待預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。 [0063] B13.如B12所述的方法,其中所述數(shù)據(jù)寫(xiě)入操作包括:
[0064]如果所述序列號(hào)等于第一索引,則頭索引增加1,將待寫(xiě)入數(shù)據(jù)寫(xiě)入第一索引指向 的元素中,序列號(hào)增加1。
[0065] B14.如B12所述的方法,其中所述數(shù)據(jù)寫(xiě)入操作包括:
[0066]如果所述序列號(hào)大于第一索引,則重新向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),如果重寫(xiě)次數(shù)達(dá)到 預(yù)設(shè)的最大重寫(xiě)次數(shù),則判斷數(shù)據(jù)寫(xiě)入失敗。
[0067] B15.如B12所述的方法,其中所述數(shù)據(jù)寫(xiě)入操作包括:
[0068]如果所述序列號(hào)小于第一索引,則判斷當(dāng)前循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。
[0069] B16.如B12所述的方法,其中所述數(shù)據(jù)讀取操作包括:
[0070]如果所述序列號(hào)減1的值等于第二索引,則尾索引增加1,將待讀取數(shù)據(jù)從第二索 引指向的元素中讀取出來(lái),序列號(hào)增加數(shù)組長(zhǎng)度再減去1。
[0071] B17.如B12所述的方法,其中所述數(shù)據(jù)讀取操作包括:
[0072] 如果所述序列號(hào)減1的值大于第二索引,則重新從循環(huán)隊(duì)列讀取數(shù)據(jù),如果重寫(xiě)次 數(shù)達(dá)到最大重讀次數(shù),則判斷數(shù)據(jù)寫(xiě)入失敗。
[0073] B18.如B12所述的方法,其中所述數(shù)據(jù)讀取操作包括:
[0074]如果所述序列號(hào)減1的值小于第二索引,則判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失 敗。
[0075] B19.如B12-18中任一項(xiàng)所述的方法,其中所述數(shù)據(jù)包括日志任務(wù)。
[0076] B20.如B19所述的方法,還包括:
[0077]如果所述日志任務(wù)寫(xiě)入失敗,則由所述生產(chǎn)者線程執(zhí)行日志任務(wù),生成日志文件。 [0078] B21.如B19所述的方法,還包括:
[0079] 如果所述日志任務(wù)讀取成功,則由所述消費(fèi)者線程執(zhí)行日志任務(wù),生成日志文件。
[0080] B22.如B19所述的方法,其中所述數(shù)據(jù)讀取操作還包括:
[0081 ]如果所述日志任務(wù)讀取失敗,則等待預(yù)定時(shí)間后,重新從循環(huán)隊(duì)列讀取日志任務(wù)。 [0082]在此處所提供的說(shuō)明書(shū)中,說(shuō)明了大量具體細(xì)節(jié)。然而,能夠理解,本發(fā)明的實(shí)施 例可以在沒(méi)有這些具體細(xì)節(jié)的情況下被實(shí)踐。在一些實(shí)例中,并未詳細(xì)示出公知的方法、結(jié) 構(gòu)和技術(shù),以便不模糊對(duì)本說(shuō)明書(shū)的理解。
[0083]類似地,應(yīng)當(dāng)理解,為了精簡(jiǎn)本公開(kāi)并幫助理解各個(gè)發(fā)明方面中的一個(gè)或多個(gè),在 上面對(duì)本發(fā)明的示例性實(shí)施例的描述中,本發(fā)明的各個(gè)特征有時(shí)被一起分組到單個(gè)實(shí)施 例、圖、或者對(duì)其的描述中。然而,并不應(yīng)將該公開(kāi)的方法解釋成反映如下意圖:即所要求保 護(hù)的本發(fā)明要求比在每個(gè)權(quán)利要求中所明確記載的特征更多特征。更確切地說(shuō),如下面的 權(quán)利要求書(shū)所反映的那樣,發(fā)明方面在于少于前面公開(kāi)的單個(gè)實(shí)施例的所有特征。因此,遵 循【具體實(shí)施方式】的權(quán)利要求書(shū)由此明確地并入該【具體實(shí)施方式】,其中每個(gè)權(quán)利要求本身都 作為本發(fā)明的單獨(dú)實(shí)施例。
[0084]本領(lǐng)域那些技術(shù)人員應(yīng)該理解,本發(fā)明可以在軟件、固件、硬件或者其結(jié)合中實(shí) 現(xiàn)。本發(fā)明可以包括在具有計(jì)算機(jī)可用介質(zhì)的物品中。該介質(zhì)在其中具有例如計(jì)算機(jī)可讀 程序代碼裝置或者邏輯(例如:指令,代碼,命令等)來(lái)提供和使用本發(fā)明的能力。該制造物 品可作為計(jì)算機(jī)系統(tǒng)的一部分或者單獨(dú)出售。
[0085]本領(lǐng)域那些技術(shù)人員應(yīng)當(dāng)理解在本文所公開(kāi)的示例中的設(shè)備的模塊或單元或組 件可以布置在如該實(shí)施例中所描述的設(shè)備中,或者可替換地可以定位在與該示例中的設(shè)備 不同的一個(gè)或多個(gè)設(shè)備中。前述示例中的模塊可以組合為一個(gè)模塊或者此外可以分成多個(gè) 子模塊。
[0086]本領(lǐng)域那些技術(shù)人員可以理解,可以對(duì)實(shí)施例中的設(shè)備中的模塊進(jìn)行自適應(yīng)性地 改變并且把它們?cè)O(shè)置在與該實(shí)施例不同的一個(gè)或多個(gè)設(shè)備中??梢园褜?shí)施例中的模塊或單 元或組件組合成一個(gè)模塊或單元或組件,以及此外可以把它們分成多個(gè)子模塊或子單元或 子組件。除了這樣的特征和/或過(guò)程或者單元中的至少一些是相互排斥之外,可以采用任何 組合對(duì)本說(shuō)明書(shū)(包括伴隨的權(quán)利要求、摘要和附圖)中公開(kāi)的所有特征以及如此公開(kāi)的任 何方法或者設(shè)備的所有過(guò)程或單元進(jìn)行組合。除非另外明確陳述,本說(shuō)明書(shū)(包括伴隨的權(quán) 利要求、摘要和附圖)中公開(kāi)的每個(gè)特征可以由提供相同、等同或相似目的的替代特征來(lái)代 替。
[0087]此外,本領(lǐng)域的技術(shù)人員能夠理解,盡管在此所述的一些實(shí)施例包括其它實(shí)施例 中所包括的某些特征而不是其它特征,但是不同實(shí)施例的特征的組合意味著處于本發(fā)明的 范圍之內(nèi)并且形成不同的實(shí)施例。例如,在下面的權(quán)利要求書(shū)中,所要求保護(hù)的實(shí)施例的任 意之一都可以以任意的組合方式來(lái)使用。
[0088]此外,所述實(shí)施例中的一些在此被描述成可以由計(jì)算機(jī)系統(tǒng)的處理器或者由執(zhí)行 所述功能的其它裝置實(shí)施的方法或方法元素的組合。因此,具有用于實(shí)施所述方法或方法 元素的必要指令的處理器形成用于實(shí)施該方法或方法元素的裝置。此外,裝置實(shí)施例的在 此所述的元素是如下裝置的例子:該裝置用于實(shí)施由為了實(shí)施該發(fā)明的目的的元素所執(zhí)行 的功能。
[0089]如在此所使用的那樣,除非另行規(guī)定,使用序數(shù)詞"第一"、"第二"、"第三"等等來(lái) 描述普通對(duì)象僅僅表示涉及類似對(duì)象的不同實(shí)例,并且并不意圖暗示這樣被描述的對(duì)象必 須具有時(shí)間上、空間上、排序方面或者以任意其它方式的給定順序。
[0090]盡管根據(jù)有限數(shù)量的實(shí)施例描述了本發(fā)明,但是受益于上面的描述,本技術(shù)領(lǐng)域 內(nèi)的技術(shù)人員明白,在由此描述的本發(fā)明的范圍內(nèi),可以設(shè)想其它實(shí)施例。此外,應(yīng)當(dāng)注意, 本說(shuō)明書(shū)中使用的語(yǔ)言主要是為了可讀性和教導(dǎo)的目的而選擇的,而不是為了解釋或者限 定本發(fā)明的主題而選擇的。因此,在不偏離所附權(quán)利要求書(shū)的范圍和精神的情況下,對(duì)于本 技術(shù)領(lǐng)域的普通技術(shù)人員來(lái)說(shuō)許多修改和變更都是顯而易見(jiàn)的。對(duì)于本發(fā)明的范圍,對(duì)本 發(fā)明所做的公開(kāi)是說(shuō)明性的,而非限制性的,本發(fā)明的范圍由所附權(quán)利要求書(shū)限定。
【主權(quán)項(xiàng)】
1. 一種數(shù)據(jù)傳輸裝置,所述裝置包括: 數(shù)據(jù)存儲(chǔ)器,適于以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù),所述循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和 尾索引,循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng)一個(gè)序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo); 寫(xiě)接口,適于接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令,根據(jù)所述寫(xiě)入指令向循環(huán)隊(duì)列 寫(xiě)入數(shù)據(jù),所述向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù)包括讀取頭索引并將其賦值給第一索引,通過(guò)判斷第 一索引指向的元素的序列號(hào)與第一索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作; 讀接口,適于接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,根據(jù)所述讀取指令從循環(huán)隊(duì)列 讀取數(shù)據(jù),所述從循環(huán)隊(duì)列讀取數(shù)據(jù)包括讀取尾索引并將其賦值給第二索引,通過(guò)判斷第 二索引指向的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操作; 其中,所述頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。2. 如權(quán)利要求1所述的裝置,所述寫(xiě)接口進(jìn)一步適于: 當(dāng)所述序列號(hào)等于第一索引時(shí),頭索引增加1,將待寫(xiě)入數(shù)據(jù)寫(xiě)入第一索引指向的元素 中,序列號(hào)增加1。3. 如權(quán)利要求1所述的裝置,所述寫(xiě)接口進(jìn)一步適于: 當(dāng)所述序列號(hào)大于第一索引時(shí),重新向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù)設(shè)的最 大重寫(xiě)次數(shù)時(shí),判斷數(shù)據(jù)寫(xiě)入失敗。4. 如權(quán)利要求1所述的裝置,所訴寫(xiě)接口進(jìn)一步適于: 當(dāng)所述序列號(hào)小于第一索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已滿,數(shù)據(jù)寫(xiě)入失敗。5. 如權(quán)利要求1所述的裝置,所述讀接口進(jìn)一步適于: 當(dāng)所述序列號(hào)減1的值等于第二索引時(shí),尾索引增加1,將待讀取數(shù)據(jù)從第二索引指向 的元素中讀取出來(lái),序列號(hào)增加數(shù)組長(zhǎng)度再減去1。6. 如權(quán)利要求1所述的裝置,所述讀接口進(jìn)一步適于: 當(dāng)所述序列號(hào)減1的值大于第二索引時(shí),重新從循環(huán)隊(duì)列讀取數(shù)據(jù),當(dāng)重寫(xiě)次數(shù)達(dá)到預(yù) 設(shè)的最大重讀次數(shù)時(shí),判斷數(shù)據(jù)讀取失敗。7. 如權(quán)利要求1所述的裝置,所述讀接口進(jìn)一步適于: 當(dāng)所述序列號(hào)減1的值小于第二索引時(shí),判斷當(dāng)前循環(huán)隊(duì)列已空,數(shù)據(jù)讀取失敗。8. 如權(quán)利要求1-7中任一項(xiàng)所述的裝置,其中所述數(shù)據(jù)包括日志任務(wù)。9. 如權(quán)利要求8所述的裝置,其中: 所述生產(chǎn)者線程在所述日志任務(wù)寫(xiě)入失敗時(shí),執(zhí)行日志任務(wù),生成日志文件。10. -種數(shù)據(jù)傳輸方法,適于對(duì)以循環(huán)隊(duì)列存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)存儲(chǔ)器進(jìn)行寫(xiě)入和讀取操 作,其中所述循環(huán)隊(duì)列以數(shù)組結(jié)構(gòu)實(shí)現(xiàn),具有頭索引和尾索引,循環(huán)隊(duì)列中的每個(gè)元素對(duì)應(yīng) 一個(gè)序列號(hào),序列號(hào)初始化為元素對(duì)應(yīng)的數(shù)組下標(biāo),所述方法包括: 接收一個(gè)或多個(gè)生產(chǎn)者線程的寫(xiě)入指令,根據(jù)所述寫(xiě)入指令向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù),所 述向循環(huán)隊(duì)列寫(xiě)入數(shù)據(jù)包括讀取頭索引并將其賦值給第一索引,通過(guò)判斷第一索引指向的 元素的序列號(hào)與第一索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)寫(xiě)入操作; 接收一個(gè)或多個(gè)消費(fèi)者線程的讀取指令,根據(jù)所述讀取指令從循環(huán)隊(duì)列讀取數(shù)據(jù),所 述從循環(huán)隊(duì)列讀取數(shù)據(jù)包括讀取尾索引并將其賦值給第二索引,通過(guò)判斷第二索引指向的 元素的序列號(hào)減1的值與第二索引的大小,執(zhí)行相應(yīng)的數(shù)據(jù)讀取操作; 其中,所述頭索引、尾索引、序列號(hào)、第一索引和第二索引均是原子對(duì)象。
【文檔編號(hào)】G06F9/54GK105868031SQ201610173906
【公開(kāi)日】2016年8月17日
【申請(qǐng)日】2016年3月24日
【發(fā)明人】王冠惟
【申請(qǐng)人】車(chē)智互聯(lián)(北京)科技有限公司