本發(fā)明涉及計(jì)算機(jī)領(lǐng)域,尤其涉及一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法及裝置。
背景技術(shù):
多進(jìn)程的系統(tǒng)一般是基于虛擬內(nèi)存的系統(tǒng),比如像Linux和較新的Windows系統(tǒng),進(jìn)程的地址空間是相互獨(dú)立的。進(jìn)程之間要交互各自的私有數(shù)據(jù)有多種通信機(jī)制,比如消息隊(duì)列、管道、套接字以及文件等,這些進(jìn)程間通信機(jī)制基本都要經(jīng)過多次的數(shù)據(jù)拷貝才能達(dá)到共享數(shù)據(jù)的目的,開銷過大。
為了避免進(jìn)程間在交互各自的私有數(shù)據(jù)時,會出現(xiàn)開銷過大的問題,現(xiàn)有技術(shù)中提出了基于內(nèi)存池來進(jìn)行數(shù)據(jù)共享的方法,該方法的基本原理為:首先需要創(chuàng)建共享內(nèi)存池,然后將該創(chuàng)建的共享內(nèi)存池分配給各個進(jìn)程,其共享內(nèi)存池的管理思想是先將各種大小的內(nèi)存塊鏈接在一起,當(dāng)需要為進(jìn)程分配內(nèi)存時,依次遍歷查看各個空閑的內(nèi)存塊,找到滿足要求的內(nèi)存塊后,再進(jìn)行拆分分配,釋放后又要將相鄰內(nèi)存塊進(jìn)行合并的動作。上述的方案中由于在為進(jìn)程分配共享內(nèi)存塊時,需要遍歷該內(nèi)存池中的每個內(nèi)存塊,再找到符合要求的內(nèi)存塊,這樣使得最終為進(jìn)程分配到共享內(nèi)存塊所花費(fèi)的時間較長。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明的實(shí)施例提供一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法及裝置,用以解決現(xiàn)有技術(shù)中為進(jìn)程分配內(nèi)存塊時所花費(fèi)的時間較長的問題。
為達(dá)到上述目的,本發(fā)明的實(shí)施例采用如下技術(shù)方案:
本發(fā)明實(shí)施例的第一方面,提供一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法,所述方法包括:
進(jìn)程基于預(yù)設(shè)鍵值創(chuàng)建共享內(nèi)存,所述共享內(nèi)存包括M個大小相同的共享內(nèi)存大塊,每個共享內(nèi)存大塊中包括N個共享內(nèi)存小塊;所述M和N均大于或等于2;
所述進(jìn)程在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,所述共享內(nèi)存控制塊包括由第一共享內(nèi)存大塊的索引鏈接構(gòu)成的第一鏈表,由第二共享內(nèi)存大塊的索引鏈接構(gòu)成的第二鏈表,由第三共享內(nèi)存大塊的索引鏈接構(gòu)成的第三鏈表,其中,第一共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑。
所述進(jìn)程在其私有內(nèi)存中創(chuàng)建映射關(guān)系表;所述映射關(guān)系表用于指示共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系;
所述進(jìn)程從所述第二鏈表和/或所述第三鏈表查找用于分配給所述進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在所述映射關(guān)系表查找所述目標(biāo)共享內(nèi)存大塊的起始地址,以便向所述目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。
本發(fā)明實(shí)施例的第二方面,提供一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理裝置,所述裝置包括:
第一創(chuàng)建模塊,用于基于預(yù)設(shè)鍵值創(chuàng)建共享內(nèi)存,所述共享內(nèi)存包括M個大小相同的共享內(nèi)存大塊,每個共享內(nèi)存大塊中包括N個共享內(nèi)存小塊;所述M和N均大于或等于2;
所述第一創(chuàng)建模塊,還用于在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,所述共享內(nèi)存控制塊包括由第一共享內(nèi)存大塊的索引鏈接構(gòu)成的第一鏈表,由第二共享內(nèi)存大塊的索引鏈接構(gòu)成的第二鏈表,由第三共享內(nèi)存大塊的索引鏈接構(gòu)成的第三鏈表,其中,第一共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑。
第二創(chuàng)建模塊,用于在進(jìn)程的私有內(nèi)存中創(chuàng)建映射關(guān)系表;所述映射關(guān)系表用于指示共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系;
分配模塊,用于從所述第二鏈表和/或所述第三鏈表中查找用于分配給所述進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在所述映射關(guān)系表中查找所述目標(biāo)共享內(nèi)存大塊的起始地址,以便向所述目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。
本發(fā)明實(shí)施例提供的多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法及裝置,相比于現(xiàn)有技術(shù),本方案進(jìn)程首先在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,該共享內(nèi)存控制塊中包括三種不同狀態(tài)的鏈表,其中:第一鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二鏈表中的共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑;其次,該進(jìn)程創(chuàng)建映射關(guān)系表,該映射關(guān)系表中存儲的是共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系;進(jìn)程在為自身分配共享內(nèi)存小塊時,直接從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在上述的映射關(guān)系表中查找目標(biāo)共享內(nèi)存大塊的起始地址,以便于向目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。這樣就避免了現(xiàn)有技術(shù)中依次遍歷查看各個空閑的內(nèi)存塊,從而節(jié)省了進(jìn)程分配內(nèi)存塊時所花費(fèi)的時間,進(jìn)而提高系統(tǒng)的運(yùn)行速率。
附圖說明
為了更清楚地說明本發(fā)明實(shí)施例或現(xiàn)有技術(shù)中的技術(shù)方案,下面將對實(shí)施例或現(xiàn)有技術(shù)描述中所需要使用的附圖作簡單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明的一些實(shí)施例,對于本領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動性的前提下,還可以根據(jù)這些附圖獲得其他的附圖。
圖1為本發(fā)明實(shí)施例提供的一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法的方法流程圖;
圖2為本發(fā)明實(shí)施例提供的一種共享內(nèi)存的管理示意圖;
圖3為本發(fā)明實(shí)施例提供的一種管理進(jìn)程與業(yè)務(wù)進(jìn)程間訪問共享內(nèi)存的示意圖;
圖4為本發(fā)明實(shí)施例提供的一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理裝置的結(jié)構(gòu)示意圖;
圖5為本發(fā)明實(shí)施例提供的另一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理裝置的結(jié)構(gòu)示意圖。
具體實(shí)施方式
下面將結(jié)合本發(fā)明實(shí)施例中的附圖,對本發(fā)明實(shí)施例中的技術(shù)方案進(jìn)行清楚、完整地描述,顯然,所描述的實(shí)施例僅僅是本發(fā)明一部分實(shí)施例,而不是全部的實(shí)施例。基于本發(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有做出創(chuàng)造性勞動前提下所獲得的所有其他實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。
為了便于清楚描述本發(fā)明實(shí)施例的技術(shù)方案,在本發(fā)明的實(shí)施例中,采用了“第一”、“第二”等字樣對功能或作用基本相同的相同項(xiàng)或相似項(xiàng)進(jìn)行區(qū)分,本領(lǐng)域技術(shù)人員可以理解“第一”、“第二”等字樣并不對數(shù)量和執(zhí)行次序進(jìn)行限定。
本文中術(shù)語“和/或”,僅僅是一種描述關(guān)聯(lián)對象的關(guān)聯(lián)關(guān)系,表示可以存在三種關(guān)系,例如,A和/或B,可以表示:單獨(dú)存在A,同時存在A和B,單獨(dú)存在B這三種情況。另外,本文中字符“/”,一般表示前后關(guān)聯(lián)對象是一種“或”的關(guān)系。
術(shù)語定義:
進(jìn)程:本發(fā)明上下文中,進(jìn)程是在計(jì)算機(jī)中運(yùn)行的應(yīng)用程序?qū)嶓w,其被分配給計(jì)算機(jī)設(shè)備的處理器,并由處理器執(zhí)行。
業(yè)務(wù)進(jìn)程:本發(fā)明上下文中,業(yè)務(wù)進(jìn)程指運(yùn)行特定協(xié)議業(yè)務(wù)的進(jìn)程應(yīng)用程序?qū)嶓w,比如網(wǎng)絡(luò)時間協(xié)議(英文:Network Time Protocol,簡稱:NTP)業(yè)務(wù)進(jìn)程。
管理進(jìn)程:本發(fā)明上下文中,管理進(jìn)程指統(tǒng)一管理并顯示業(yè)務(wù)進(jìn)程的內(nèi)部私有數(shù)據(jù)等,比如在管理進(jìn)程中有對用戶提供的命令行界面(英文:Command-line Interface,簡稱:CLI),可以針對某個具體的業(yè)務(wù)進(jìn)程進(jìn)行信息獲取并顯示。
共享內(nèi)存:是一種進(jìn)程間通信的方式,也是最快的進(jìn)程間通信(英文:Inter-Process Communication,簡稱:IPC)形式。兩個不同進(jìn)程A、B共享內(nèi)存的意思是同一塊物理內(nèi)存被映射到進(jìn)程A、B各自的進(jìn)程虛擬地址空間。進(jìn)程A可以即時看到進(jìn)程B對共享內(nèi)存中數(shù)據(jù)的更新,反之亦然。
共享內(nèi)存大塊:通過系統(tǒng)調(diào)用接口分配出來的大塊的共享內(nèi)存,比如在linux系統(tǒng)下面,通過mmap系統(tǒng)調(diào)用接口映射一塊4096字節(jié)的共享內(nèi)存大塊。
共享內(nèi)存小塊:將共享內(nèi)存大塊拆分成固定大小的共享內(nèi)存小塊,比如在mmap分配4096內(nèi)存出來后,將4096拆分為64塊大小為64字節(jié)的共享內(nèi)存小塊,具體共享內(nèi)存大塊和共享內(nèi)存小塊的大小可以根據(jù)具體業(yè)務(wù)情況進(jìn)行設(shè)置。
本發(fā)明實(shí)施例提供一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法,如圖1所示,該方法包括:
101、進(jìn)程基于預(yù)設(shè)鍵值創(chuàng)建共享內(nèi)存,該共享內(nèi)存包括M個大小相同的共享內(nèi)存大塊,每個共享內(nèi)存大塊中包括N個共享內(nèi)存小塊;M和N均大于或等于2。
可選的,上述的預(yù)設(shè)鍵值可以是每個進(jìn)程預(yù)先進(jìn)行統(tǒng)一所設(shè)定好的,也可以是基于指定的文件所生成的一個預(yù)設(shè)鍵值。例如,每個進(jìn)程基于指定的文件(如/shm/shm_cache,linux系統(tǒng)下可基于這個文件來生成鍵值,每個進(jìn)程基于相同的文件來創(chuàng)建同一個共享內(nèi)存)來創(chuàng)建這個共享內(nèi)存,且使用進(jìn)程內(nèi)部變量shmCacheAddr來保存這個映射出來的地址。
示例性的,上述的內(nèi)存大塊的個數(shù)可以一次性創(chuàng)建好,比如創(chuàng)建2048個,也可以是動態(tài)進(jìn)行增長的,而對于動態(tài)增長在這里不進(jìn)行說明,具體參照現(xiàn)有技術(shù)。
102、進(jìn)程在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,該共享內(nèi)存控制塊包括由第一共享內(nèi)存大塊的索引鏈接構(gòu)成的第一鏈表,由第二共享內(nèi)存大塊的索引鏈接構(gòu)成的第二鏈表,由第三共享內(nèi)存大塊的索引鏈接構(gòu)成的第三鏈表。
其中,上述的第一共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑。
需要說明的是,上述的第一鏈表、第二鏈表以及第三鏈表均可以為雙向循環(huán)鏈表或者單向循環(huán)鏈表。
示例性的,參照圖2所示的示意圖,上述的三個鏈表分別為Full(0)、Partial(1)和free(2),以Free鏈為例,具體參照圖2中的標(biāo)號2,該free鏈頭preNode值為6,表示其前一個結(jié)點(diǎn)為數(shù)組索引6,nxtNode值為5,表示其后一個結(jié)點(diǎn)為數(shù)組索引5;數(shù)組索引5中shm_cache_node的preNode值為2,表示其前一個結(jié)點(diǎn)為數(shù)組索引2,nxtNode值為6,表示其后一個結(jié)點(diǎn)為數(shù)組索引6;依此類推,即以數(shù)組下標(biāo)的值為索引來鏈接這些同類的塊,形成一個雙向的循環(huán)鏈表。由各個進(jìn)程中映射的共享內(nèi)存指針值shmCacheAddr加上這些索引即可得到指定shm_cache_node塊的地址,從而訪問其成員值。
103、進(jìn)程在其私有內(nèi)存中創(chuàng)建映射關(guān)系表。
本發(fā)明實(shí)施例中的映射關(guān)系表用于指示共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系。
示例性的,上述的私有內(nèi)存為進(jìn)程的虛擬地址空間,通常情況下,在進(jìn)程啟動時,Linux系統(tǒng)會為每個進(jìn)程分配4GB的虛擬地址空間來供進(jìn)程的運(yùn)行使用。
104、進(jìn)程從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在映射關(guān)系表查找目標(biāo)共享內(nèi)存大塊的起始地址,以便向目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。
優(yōu)選的,為了減少共享內(nèi)存中出現(xiàn)的內(nèi)存碎片的數(shù)量,上述的步驟104中的進(jìn)程從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引具體包括以下內(nèi)容:
104a、進(jìn)程從第二鏈表中按照第二鏈表中索引鏈接的順序,依次查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,直至查找到為止。
104b、若第二鏈表中不存在用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,或第二鏈表中不存在共享內(nèi)存大塊的索引,則按照第三鏈表中索引鏈接的順序確定第三鏈表中的至少一個索引,作為分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引。
示例性的,上述的第二鏈表中不存在共享內(nèi)存大塊的索引包括兩方面的內(nèi)容,一方面,當(dāng)進(jìn)程第一次運(yùn)行的時候,由于共享內(nèi)存大塊中的共享內(nèi)存小塊均空閑,因此這里的第二鏈表中為空,即未存儲任何索引;另一方面,在第二鏈表中所存儲的僅僅是一些其他的標(biāo)識,例如為標(biāo)識0,而該標(biāo)識0不代表任何共享內(nèi)存大塊的索引。
示例性的,上述按照第三鏈表中索引鏈接的順序確定第三鏈表中的至少一個索引具體為:由于進(jìn)程自身的需求,可能一個共享內(nèi)存大塊不能滿足進(jìn)程寫數(shù)據(jù)的需求,可能會需要兩個甚至多個共享內(nèi)存大塊,因此這里需要在第三鏈表中確定至少一個索引。
示例性的,上述的步驟104中的進(jìn)程從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引具體包括以下內(nèi)容:
104c、進(jìn)程直接從第三鏈表中按照第三鏈表中索引鏈接的順序,依次查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引。
本發(fā)明實(shí)施例提供的多進(jìn)程系統(tǒng)中共享內(nèi)存的管理方法,相比于現(xiàn)有技術(shù),本方案進(jìn)程首先在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,該共享內(nèi)存控制塊中包括三種不同狀態(tài)的鏈表,其中:第一鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二鏈表中的共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑;其次,該進(jìn)程創(chuàng)建映射關(guān)系表,該映射關(guān)系表中存儲的是共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系;進(jìn)程在為自身分配共享內(nèi)存小塊時,直接從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在上述的映射關(guān)系表中查找目標(biāo)共享內(nèi)存大塊的起始地址,以便于向目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。這樣就避免了現(xiàn)有技術(shù)中依次遍歷查看各個空閑的內(nèi)存塊,從而節(jié)省了進(jìn)程分配內(nèi)存塊時所花費(fèi)的時間,進(jìn)而提高系統(tǒng)的運(yùn)行速率。
可選的,若進(jìn)程從第二鏈表中查找到用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,此時需要給該第二鏈表中的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊中寫數(shù)據(jù),具體的,該方法還包括以下內(nèi)容:
A1、進(jìn)程根據(jù)在映射關(guān)系表查找到的目標(biāo)共享內(nèi)存大塊的起始地址、目標(biāo)共享內(nèi)存大塊中的空閑管理區(qū)的大小以及目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊被占用的個數(shù)確定出空閑的共享內(nèi)存小塊的起始地址。
A2、進(jìn)程從空閑的共享內(nèi)存小塊的起始地址處開始寫數(shù)據(jù),將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值增加x。
其中,上述的x為被占用的空閑共享內(nèi)存小塊的個數(shù)。例如,若進(jìn)程寫從空閑的共享內(nèi)存小塊的起始地址處寫數(shù)據(jù),將數(shù)據(jù)寫完需要占用3個空閑的共享內(nèi)存小塊,則此時需要將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值加3。
在上述的進(jìn)程分配共享內(nèi)存小塊后,使得該共享內(nèi)存小塊所在的共享內(nèi)存大塊的狀態(tài)發(fā)生變化,進(jìn)而需要更新三個鏈表中所鏈接的共享內(nèi)存大塊索引??蛇x的,該方法還包括:
B1、若第二鏈表中的第二共享內(nèi)存大塊中的所有共享內(nèi)存小塊被占用,則進(jìn)程將第二共享內(nèi)存大塊的索引鏈接到第一鏈表中;或
B2、若第三鏈表中的第三共享內(nèi)存大塊中的所有共享內(nèi)存小塊被占用,則進(jìn)程將第三共享內(nèi)存大塊的索引鏈接到第一鏈表中;或
B3、若第三鏈表中的第三共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,則進(jìn)程將第三共享內(nèi)存大塊的索引鏈接到第二鏈表中。
為了使得其他進(jìn)程對內(nèi)存空間的需求得到滿足,還需要將分配到的共享內(nèi)存大塊回歸至系統(tǒng)??蛇x的,該方法還包括以下內(nèi)容:
C1、進(jìn)程釋放為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊,將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值減少y。
C2、若共享內(nèi)存大塊中的計(jì)數(shù)器中的數(shù)值減為0,則進(jìn)程將共享內(nèi)存大塊在本進(jìn)程內(nèi)刪除。
其中,上述的y為被釋放的共享內(nèi)存小塊的個數(shù)。例如,若進(jìn)程釋放了目標(biāo)共享內(nèi)存大塊中的2個共享內(nèi)存小塊的,則此時需要將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值減2。
優(yōu)選的,為了保證設(shè)備的正常運(yùn)轉(zhuǎn),需要快速的釋放上述的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊,上述的步驟C1中進(jìn)程釋放為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊具體包括以下內(nèi)容:
D1、根據(jù)共享內(nèi)存小塊中記錄的共享內(nèi)存大塊索引定位得到目標(biāo)共享內(nèi)存大塊的起始地址。
D2、從目標(biāo)共享內(nèi)存大塊的起始地址處開始,將為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊設(shè)置為空閑。
示例性的,上述的將目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊釋放可以是直接將共享內(nèi)存小塊的索引添加到目標(biāo)共享內(nèi)存大塊中的空閑塊管理區(qū)中。由于空閑塊管理區(qū)中存儲的就是空閑的共享內(nèi)存小塊的索引,因此釋放的時候只需要修改空閑管理區(qū)內(nèi)的控制信息,指示此共享內(nèi)存小塊釋放后是空閑可用狀態(tài)。
在上述的進(jìn)程釋放目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊后,使得該共享內(nèi)存小塊所在的目標(biāo)共享內(nèi)存大塊的狀態(tài)發(fā)生變化,進(jìn)而需要更新三個鏈表中所鏈接的共享內(nèi)存大塊索引??蛇x的,該方法還包括:
E1、若目標(biāo)共享內(nèi)存大塊中的所有共享內(nèi)存小塊被釋放,則進(jìn)程將目標(biāo)共享內(nèi)存大塊的索引鏈接到第三鏈表中。
E2、若目標(biāo)共享內(nèi)存大塊中的部分共享內(nèi)存小塊被釋放,則進(jìn)程將目標(biāo)共享內(nèi)存大塊的索引鏈接到第二鏈表中。
下面基于圖1所示的多進(jìn)程系統(tǒng)中的共享內(nèi)存管理方法,參照圖2所示的共享內(nèi)存的管理流程示意圖,進(jìn)行描述本方案中的具體管理過程。
該共享內(nèi)存統(tǒng)一管理的基本思想包括以下內(nèi)容:首先是共享內(nèi)存緩存shm_cache的管理,其維護(hù)進(jìn)程中所有的共享內(nèi)存大塊shm_node的狀態(tài),包括full(表頭位置為數(shù)組索引0,此表上的shm_node管理的所有共享內(nèi)存小塊都已被分配)、partial(表頭位置為數(shù)組索引1,此表上的shm_node管理的部分共享內(nèi)存小塊未被分配)、free(表頭位置為數(shù)組索引2,此表上的shm_node管理的所有共享內(nèi)存小塊都未被分配)這三個狀態(tài),業(yè)務(wù)進(jìn)程有需要分配共享內(nèi)存小塊時優(yōu)先從partial表中分配。
其次,就是分配給業(yè)務(wù)進(jìn)程使用的共享內(nèi)存小塊,具體細(xì)節(jié)如下(共享內(nèi)存創(chuàng)建接口使用系統(tǒng)原生的接口即可,比如linux系統(tǒng)中的mmap或shmget均可,任何多進(jìn)程環(huán)境并支持共享內(nèi)存機(jī)制的系統(tǒng)均在此發(fā)明保護(hù)范圍,這里以linux系統(tǒng)進(jìn)行示例說明):
(1)共享內(nèi)存控制塊(以下簡稱:shm_cache)創(chuàng)建:業(yè)務(wù)進(jìn)程啟動后都會默認(rèn)創(chuàng)建shm_cache,且每個進(jìn)程基于指定的文件(如/shm/shm_cache,linux系統(tǒng)下可基于這個文件來生成鍵值,每個業(yè)務(wù)進(jìn)程基于相同的文件來創(chuàng)建同一個共享內(nèi)存)來創(chuàng)建這個共享內(nèi)存,且使用業(yè)務(wù)進(jìn)程內(nèi)部變量shmCacheAddr(圖2中標(biāo)號1所示)來保存這個映射出來的地址。shm_cache管理的共享內(nèi)存大塊(以下簡稱:shm_node)個數(shù)(對應(yīng)圖示的共享內(nèi)存大塊結(jié)點(diǎn)(以下簡稱:shm_cache_node),每個shm_cache_node對應(yīng)一個shm_node)一次性創(chuàng)建好,比如創(chuàng)建2048個(當(dāng)然這里管理的shm_node個數(shù)也可以動態(tài)增長,便于說明方案,這里動態(tài)增長就不說明了,但屬于此方案范圍)。
(2)shm_cache如何管理shm_node:如圖2中標(biāo)號2所示,這里以free鏈為例,free鏈頭preNode值為6,表示相鄰兩個結(jié)點(diǎn)中的前一個結(jié)點(diǎn)為數(shù)組索引6,nxtNode值為5,表示相鄰兩個結(jié)點(diǎn)中的后一個結(jié)點(diǎn)為數(shù)組索引5;數(shù)組索引5中shm_cache_node的preNode值為2,表示相鄰兩個結(jié)點(diǎn)中的前一個結(jié)點(diǎn)為數(shù)組索引2,nxtNode值為6,表示相鄰兩個結(jié)點(diǎn)中的后一個結(jié)點(diǎn)為數(shù)組索引6;依此類推,即以數(shù)組下標(biāo)的值為索引來鏈接這些同類的塊,形成一個雙向的循環(huán)鏈表。由各個業(yè)務(wù)進(jìn)程中映射的共享內(nèi)存指針值shmCacheAddr加上這些索引即可得到指定shm_cache_node的地址,從而訪問其成員值。
(3)映射關(guān)系表(以下簡稱shm_map:)創(chuàng)建:shm_map是存儲在各個業(yè)務(wù)進(jìn)程獨(dú)自分配的內(nèi)存中(即不是共享內(nèi)存),其存在主要用于將shm_cache_node和shm_node關(guān)聯(lián)起來,shm_cache_node中的shmKey(示例值為0到2047)有兩層作用,一是用于shm_map哈希表的鍵值,二是用于生成文件(如/shm/shm_node_shmKey,此文件用于共享內(nèi)存創(chuàng)建的鍵值,各個進(jìn)程可以基于此文件創(chuàng)建同一個共享內(nèi)存),業(yè)務(wù)進(jìn)程以這個文件來創(chuàng)建共享內(nèi)存,此共享內(nèi)存用于存儲shm_node的空閑塊管理區(qū)和數(shù)據(jù)區(qū)。業(yè)務(wù)進(jìn)程映射出來的共享內(nèi)存地址存儲在shm_map中的shmNodeAddr,如圖2中標(biāo)號6所示。
(4)空閑塊管理區(qū):用于管理所有未分配的共享內(nèi)存小塊,shm_node中的nxtFree指向下一個可用塊索引,下一個可用塊的對應(yīng)控制區(qū)同樣指向下下個可用塊索引,如圖2中標(biāo)號7所示,即類似shm_cache管理shm_node的方式,只是這里是單向的數(shù)組鏈表。
(5)共享內(nèi)存小塊區(qū):按業(yè)務(wù)進(jìn)程需求將共享內(nèi)存大塊劃分成固定大小,比如各業(yè)務(wù)進(jìn)程的內(nèi)存分配信息(進(jìn)程標(biāo)識、使用內(nèi)存的用戶信息、分配內(nèi)存次數(shù)、分配內(nèi)存總大小,此記錄有多條。每種業(yè)務(wù)進(jìn)程的私有信息都可以對應(yīng)一個shm_cache),這樣管理進(jìn)程可以通過遍歷這張表來顯示指定業(yè)務(wù)進(jìn)程的內(nèi)存使用信息,從而便于內(nèi)存泄露問題的定位。
這里僅是以示例進(jìn)行說明一個顯示的方法,還可以有其它方法來顯示這些信息,其它方法也屬于本發(fā)明保護(hù)范圍。比如將shm_map中的索引信息和各個業(yè)務(wù)進(jìn)程進(jìn)行綁定關(guān)聯(lián),同時規(guī)定一個shm_node只能讓一個業(yè)務(wù)進(jìn)程使用,這樣管理進(jìn)程要顯示具體的某個業(yè)務(wù)進(jìn)程私有數(shù)據(jù)時,可以直接一步到位通過索引獲取shm_node,再顯示shm_node上所有已經(jīng)分配的共享內(nèi)存小塊的存儲的數(shù)據(jù)信息。
(6)共享內(nèi)存小塊分配流程:①通過shm_cache找到可分配共享內(nèi)存小塊的shm_cache_node,獲得shmKey值,由shmKey哈希獲得shm_node起始地址,在shm_node中找到一個空閑共享內(nèi)存小塊的索引,結(jié)合shm_node的起始地址最終計(jì)算出要返回的地址(shmNodeAddr+空閑管理區(qū)大小+索引*內(nèi)存塊大小),shm_node中inUseCnt加1;②在①的過程中如果由shmKey查找失敗,則說明這是其它業(yè)務(wù)進(jìn)程所創(chuàng)建的shm_node,或者說當(dāng)前還沒有任何業(yè)務(wù)進(jìn)程來創(chuàng)建這個shm_node,本業(yè)務(wù)進(jìn)程這時候需要進(jìn)行映射動作獲取地址(鍵值為/shm/shm_node_shmKey),之后將此地址記錄到映射表shm_map中,后面流程同①;③當(dāng)通過shm_cache無法獲取可分配共享內(nèi)存小塊的共享內(nèi)存大塊結(jié)點(diǎn)時,需要新創(chuàng)建一個共享shm_node和數(shù)據(jù)區(qū),并加入shm_cache管理,同時在本業(yè)務(wù)進(jìn)程內(nèi)映射獲取共享內(nèi)存地址,后面流程同①;當(dāng)分配共享內(nèi)存小塊成功后對shm_node中的內(nèi)存使用計(jì)數(shù)器的數(shù)值增加,具體增加的數(shù)值為分配的共享內(nèi)存小塊的個數(shù)。
(7)共享內(nèi)存小塊釋放流程:這里有兩種方式①根據(jù)用戶所傳遞進(jìn)來的共享內(nèi)存小塊地址,遍歷shm_map,通過shmNodeAddr和共享內(nèi)存大塊大小(大小可以是預(yù)先設(shè)置好的)范圍找到指定映射表中的共享內(nèi)存大塊結(jié)點(diǎn),從映射表中的共享內(nèi)存大塊結(jié)點(diǎn)中獲取該共享內(nèi)存小塊地址所在的共享內(nèi)存大塊的shmNodeAddr值,將shm_node中相應(yīng)共享內(nèi)存小塊的控制區(qū)設(shè)置為空閑;②為了快速查找,在共享內(nèi)存小塊中記錄shmKey值,由shmKey定位得到shmNodeAddr,以空間換時間;釋放成功后對shm_node中內(nèi)存使用計(jì)數(shù)器的數(shù)值減少,具體減少的數(shù)值為釋放的共享內(nèi)存小塊的個數(shù)。如果計(jì)數(shù)減少為0,則將shm_node和數(shù)據(jù)區(qū)在本業(yè)務(wù)進(jìn)程內(nèi)刪除。如果此shm_node管理的所有共享內(nèi)存小塊無進(jìn)程使用,即shm_node中inUseCnt為0,則通知管理進(jìn)程將指定的shm_node和數(shù)據(jù)區(qū)進(jìn)行刪除。
(8)操作保護(hù)原則:其中對shm_cache和shm_node相關(guān)操作都需要各個業(yè)務(wù)進(jìn)程進(jìn)行互斥,而對共享內(nèi)存小塊的操作可以不需要保護(hù),保護(hù)可以考慮使用linux系統(tǒng)原生的semget機(jī)制。對shm_map的操作需要考慮進(jìn)程內(nèi)部的線程之間的互斥訪問,可以考慮使用原生的線程互斥量pthread_mutex_t機(jī)制。
參照圖3給出的管理進(jìn)程與業(yè)務(wù)進(jìn)程間訪問共享內(nèi)存的示意圖,在每個業(yè)務(wù)進(jìn)程以及管理進(jìn)程中都存在一個共享內(nèi)存管理的過程,當(dāng)業(yè)務(wù)進(jìn)程需要向共享內(nèi)存中寫數(shù)據(jù)時,都需要先調(diào)用該共享內(nèi)存管理過程(即執(zhí)行上述的圖2中的過程),然后向該共享內(nèi)存寫數(shù)據(jù)。而管理進(jìn)程在讀取該共享內(nèi)存中的數(shù)據(jù)時,仍然需要先調(diào)用該共享內(nèi)存管理過程,然后在讀取該共享內(nèi)存中的數(shù)據(jù)。從而實(shí)現(xiàn)了多個業(yè)務(wù)進(jìn)程通過共享內(nèi)存的方式將私有數(shù)據(jù)共享給管理進(jìn)程。
下面將基于圖1所示的多進(jìn)程系統(tǒng)中的共享內(nèi)存管理方法的實(shí)施例中的相關(guān)描述對本發(fā)明實(shí)施例提供的一種多進(jìn)程系統(tǒng)中的共享內(nèi)存管理裝置進(jìn)行介紹。以下實(shí)施例中與上述實(shí)施例相關(guān)的技術(shù)術(shù)語、概念等的說明可以參照上述的實(shí)施例,這里不再贅述。
本發(fā)明實(shí)施例提供的一種多進(jìn)程系統(tǒng)中共享內(nèi)存的管理裝置,如圖4所示,該裝置2包括:第一創(chuàng)建模塊21、第二創(chuàng)建模塊22以及分配模塊23,其中:
第一創(chuàng)建模塊21,用于基于預(yù)設(shè)鍵值創(chuàng)建共享內(nèi)存,共享內(nèi)存包括M個大小相同的共享內(nèi)存大塊,每個共享內(nèi)存大塊中包括N個共享內(nèi)存小塊;M和N均大于或等于2。
第一創(chuàng)建模塊21,還用于在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,共享內(nèi)存控制塊包括由第一共享內(nèi)存大塊的索引鏈接構(gòu)成的第一鏈表,由第二共享內(nèi)存大塊的索引鏈接構(gòu)成的第二鏈表,由第三共享內(nèi)存大塊的索引鏈接構(gòu)成的第三鏈表,其中,第一共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑。
第二創(chuàng)建模塊22,用于在進(jìn)程的私有內(nèi)存中創(chuàng)建映射關(guān)系表;映射關(guān)系表用于指示共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系。
分配模塊23,用于從第二鏈表和/或第三鏈表中查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在映射關(guān)系表中查找目標(biāo)共享內(nèi)存大塊的起始地址,以便向目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。
優(yōu)選的,為了減少共享內(nèi)存中出現(xiàn)的內(nèi)存碎片的數(shù)量,上述的分配模塊23在從共享內(nèi)存控制塊中的第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引時具體用于:
從第二鏈表中按照第二鏈表中索引鏈接的順序,依次查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,直至查找到為止;
若第二鏈表中不存在用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,或第二鏈表中不存在共享內(nèi)存大塊的索引,則按照第三鏈表中索引鏈接的順序確定第三鏈表中的至少一個索引,作為分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引。
可選的,若進(jìn)程從第二鏈表中查找到用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,此時需要給該第二鏈表中的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊中寫數(shù)據(jù)。如圖5所示,該裝置2還包括:確定模塊24和存儲模塊25,其中:
確定模塊24,用于根據(jù)在映射關(guān)系表查找到的目標(biāo)共享內(nèi)存大塊的起始地址、目標(biāo)共享內(nèi)存大塊中的空閑管理區(qū)的大小以及目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊被占用的個數(shù)確定出空閑的共享內(nèi)存小塊的起始地址.
存儲模塊25,用于從空閑的共享內(nèi)存小塊的起始地址處開始寫數(shù)據(jù),將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值增加x,x為被占用的空閑共享內(nèi)存小塊的個數(shù)。
在上述的進(jìn)程分配共享內(nèi)存小塊后,使得該共享內(nèi)存小塊所在的共享內(nèi)存大塊的狀態(tài)發(fā)生變化,進(jìn)而需要更新三個鏈表中所鏈接的共享內(nèi)存大塊索引??蛇x的,如圖5所示,該裝置2還包括:更新模塊26,其中:
更新模塊26用于:
若第二鏈表中的第二共享內(nèi)存大塊中的所有共享內(nèi)存小塊被占用,則進(jìn)程將第二共享內(nèi)存大塊的索引鏈接到第一鏈表中;或
若第三鏈表中的第三共享內(nèi)存大塊中的所有共享內(nèi)存小塊被占用,則進(jìn)程將第三共享內(nèi)存大塊的索引鏈接到第一鏈表中;或
若第三鏈表中的第三共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,則進(jìn)程將第三共享內(nèi)存大塊的索引鏈接到第二鏈表中。
為了使得其他進(jìn)程對內(nèi)存空間的需求得到滿足,還需要將分配到的共享內(nèi)存大塊回歸至系統(tǒng)??蛇x的,如圖5所示,該裝置2還包括:釋放模塊27,其中:
釋放模塊27,用于釋放為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊,將共享內(nèi)存大塊中的計(jì)數(shù)器的數(shù)值減少y,y為被釋放的共享內(nèi)存小塊的個數(shù);還用于若共享內(nèi)存大塊中的計(jì)數(shù)器中的數(shù)值減為0,則進(jìn)程將共享內(nèi)存大塊在本進(jìn)程內(nèi)刪除。
示例性的,上述的釋放模塊27在釋放為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊時具體用于:
根據(jù)共享內(nèi)存小塊中記錄的共享內(nèi)存大塊索引定位得到目標(biāo)共享內(nèi)存大塊的起始地址.
從目標(biāo)共享內(nèi)存大塊的起始地址處開始,將為進(jìn)程分配的目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊設(shè)置為空閑。
在上述的進(jìn)程釋放目標(biāo)共享內(nèi)存大塊中的共享內(nèi)存小塊后,使得該共享內(nèi)存小塊所在的目標(biāo)共享內(nèi)存大塊的狀態(tài)發(fā)生變化,進(jìn)而需要更新三個鏈表中所鏈接的共享內(nèi)存大塊索引。示例性的,上述的更新模塊26還用于:
若目標(biāo)共享內(nèi)存大塊中的所有共享內(nèi)存小塊被釋放,則進(jìn)程將目標(biāo)共享內(nèi)存大塊的索引鏈接到第三鏈表中。
若目標(biāo)共享內(nèi)存大塊中的部分共享內(nèi)存小塊被釋放,則進(jìn)程將目標(biāo)共享內(nèi)存大塊的索引鏈接到第二鏈表中。
本發(fā)明實(shí)施例提供的多進(jìn)程系統(tǒng)中共享內(nèi)存的管理裝置,相比于現(xiàn)有技術(shù),本方案進(jìn)程首先在共享內(nèi)存中創(chuàng)建共享內(nèi)存控制塊,該共享內(nèi)存控制塊中包括三種不同狀態(tài)的鏈表,其中:第一鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊都被占用,第二鏈表中的共享內(nèi)存大塊中的部分共享內(nèi)存小塊被占用,第三鏈表中的共享內(nèi)存大塊中的全部共享內(nèi)存小塊均空閑;其次,該進(jìn)程創(chuàng)建映射關(guān)系表,該映射關(guān)系表中存儲的是共享內(nèi)存大塊的索引與共享內(nèi)存大塊的起始地址間的映射關(guān)系;進(jìn)程在為自身分配共享內(nèi)存小塊時,直接從第二鏈表和/或第三鏈表查找用于分配給進(jìn)程的目標(biāo)共享內(nèi)存大塊的索引,并在上述的映射關(guān)系表中查找目標(biāo)共享內(nèi)存大塊的起始地址,以便于向目標(biāo)共享內(nèi)存大塊中連續(xù)空閑的共享內(nèi)存小塊寫數(shù)據(jù)。這樣就避免了現(xiàn)有技術(shù)中依次遍歷查看各個空閑的內(nèi)存塊,從而節(jié)省了進(jìn)程分配內(nèi)存塊時所花費(fèi)的時間,進(jìn)而提高系統(tǒng)的運(yùn)行速率。
通過以上的實(shí)施方式的描述,所屬領(lǐng)域的技術(shù)人員可以清楚地了解到,為描述的方便和簡潔,僅以上述各功能模塊的劃分進(jìn)行舉例說明,實(shí)際應(yīng)用中,可以根據(jù)需要而將上述功能分配由不同的功能模塊完成,即將裝置的內(nèi)部結(jié)構(gòu)劃分成不同的功能模塊,以完成以上描述的全部或者部分功能。上述描述的系統(tǒng),裝置和單元的具體工作過程,可以參考前述方法實(shí)施例中的對應(yīng)過程,在此不再贅述。
在本申請所提供的幾個實(shí)施例中,應(yīng)該理解到,所揭露的多進(jìn)程系統(tǒng)中的共享內(nèi)存管理裝置,可以通過其它的方式實(shí)現(xiàn)。例如,以上所描述的裝置實(shí)施例僅僅是示意性的,例如,所述模塊或單元的劃分,僅僅為一種邏輯功能劃分,實(shí)際實(shí)現(xiàn)時可以有另外的劃分方式,例如多個單元或組件可以結(jié)合或者可以集成到另一個系統(tǒng),或一些特征可以忽略,或不執(zhí)行。另一點(diǎn),所顯示或討論的相互之間的耦合或直接耦合或通信連接可以是通過一些接口,裝置或單元的間接耦合或通信連接,可以是電性,機(jī)械或其它的形式。
所述作為分離部件說明的單元可以是或者也可以不是物理上分開的,作為單元顯示的部件可以是或者也可以不是物理單元,即可以位于一個地方,或者也可以分布到多個網(wǎng)絡(luò)單元上??梢愿鶕?jù)實(shí)際的需要選擇其中的部分或者全部單元來實(shí)現(xiàn)本實(shí)施例方案的目的。
另外,在本發(fā)明各個實(shí)施例中的各功能單元可以集成在一個處理單元中,也可以是各個單元單獨(dú)物理存在,也可以兩個或兩個以上單元集成在一個單元中。上述集成的單元既可以采用硬件的形式實(shí)現(xiàn),也可以采用軟件功能單元的形式實(shí)現(xiàn)。
所述集成的單元如果以軟件功能單元的形式實(shí)現(xiàn)并作為獨(dú)立的產(chǎn)品銷售或使用時,可以存儲在一個計(jì)算機(jī)可讀取存儲介質(zhì)中?;谶@樣的理解,本發(fā)明的技術(shù)方案本質(zhì)上或者說對現(xiàn)有技術(shù)做出貢獻(xiàn)的部分或者該技術(shù)方案的全部或部分可以以軟件產(chǎn)品的形式體現(xiàn)出來,該計(jì)算機(jī)軟件產(chǎn)品存儲在一個存儲介質(zhì)中,包括若干指令用以使得一臺計(jì)算機(jī)設(shè)備(可以是個人計(jì)算機(jī),服務(wù)器,或者網(wǎng)絡(luò)設(shè)備等)或處理器(processor)執(zhí)行本發(fā)明各個實(shí)施例所述方法的全部或部分步驟。而前述的存儲介質(zhì)包括:U盤、移動硬盤、只讀存儲器(ROM,Read-Only Memory)、隨機(jī)存取存儲器(RAM,Random Access Memory)、磁碟或者光盤等各種可以存儲程序代碼的介質(zhì)。
以上所述,僅為本發(fā)明的具體實(shí)施方式,但本發(fā)明的保護(hù)范圍并不局限于此,任何熟悉本技術(shù)領(lǐng)域的技術(shù)人員在本發(fā)明揭露的技術(shù)范圍內(nèi),可輕易想到變化或替換,都應(yīng)涵蓋在本發(fā)明的保護(hù)范圍之內(nèi)。因此,本發(fā)明的保護(hù)范圍應(yīng)以所述權(quán)利要求的保護(hù)范圍為準(zhǔn)。