日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

共享內(nèi)存是進(jìn)程間通信中最簡(jiǎn)單的方式之一。共享內(nèi)存允許兩個(gè)或更多進(jìn)程訪問(wèn)同一塊內(nèi)存,就如同malloc()函數(shù)向不同進(jìn)程返回了指向同一個(gè)物理內(nèi)存區(qū)域的指針。當(dāng)一個(gè)進(jìn)程改變了這塊地址中的內(nèi)容的時(shí)候,其它進(jìn)程都會(huì)察覺(jué)到這個(gè)更改。

本地通信

因?yàn)樗羞M(jìn)程共享同一塊內(nèi)存,共享內(nèi)存在各種進(jìn)程間通信方式中具有最高的效率。訪問(wèn)共享內(nèi)存區(qū)域和訪問(wèn)進(jìn)程獨(dú)有的內(nèi)存區(qū)域一樣快,并不需要通過(guò)系統(tǒng)調(diào)用或者其它需要切入內(nèi)核的過(guò)程來(lái)完成。同時(shí)它也避免了對(duì)數(shù)據(jù)的各種不必要的復(fù)制。

因?yàn)橄到y(tǒng)內(nèi)核沒(méi)有對(duì)訪問(wèn)共享內(nèi)存進(jìn)行同步,您必須提供自己的同步措施。例如,在數(shù)據(jù)被寫入之前不允許進(jìn)程從共享內(nèi)存中讀取信息、不允許兩個(gè)進(jìn)程同時(shí)向同一個(gè)共享內(nèi)存地址寫入數(shù)據(jù)等。解決這些問(wèn)題的常用方法是通過(guò)使用信號(hào)量進(jìn)行同步。不過(guò),我們的程序中只有一個(gè)進(jìn)程訪問(wèn)了共享內(nèi)存,因此在集中展示了共享內(nèi)存機(jī)制的同時(shí),我們避免了讓代碼被同步邏輯搞得混亂不堪。

內(nèi)存模型

要使用一塊共享內(nèi)存,進(jìn)程必須首先分配它。隨后需要訪問(wèn)這個(gè)共享內(nèi)存塊的每一個(gè)進(jìn)程都必須將這個(gè)共享內(nèi)存綁定到自己的地址空間中。當(dāng)完成通信之后,所有進(jìn)程都將脫離共享內(nèi)存,并且由一個(gè)進(jìn)程釋放該共享內(nèi)存塊。

理解 linux 系統(tǒng)內(nèi)存模型可以有助于解釋這個(gè)綁定的過(guò)程。在 Linux 系統(tǒng)中,每個(gè)進(jìn)程的虛擬內(nèi)存是被分為許多頁(yè)面的。這些內(nèi)存頁(yè)面中包含了實(shí)際的數(shù)據(jù)。每個(gè)進(jìn)程都會(huì)維護(hù)一個(gè)從內(nèi)存地址到虛擬內(nèi)存頁(yè)面之間的映射關(guān)系。盡管每個(gè)進(jìn)程都有自己的內(nèi)存地址,不同的進(jìn)程可以同時(shí)將同一個(gè)內(nèi)存頁(yè)面映射到自己的地址空間中,從而達(dá)到共享內(nèi)存的目的。

分配一個(gè)新的共享內(nèi)存塊會(huì)創(chuàng)建新的內(nèi)存頁(yè)面。因?yàn)樗羞M(jìn)程都希望共享對(duì)同一塊內(nèi)存的訪問(wèn),只應(yīng)由一個(gè)進(jìn)程創(chuàng)建一塊新的共享內(nèi)存。再次分配一塊已經(jīng)存在的內(nèi)存塊不會(huì)創(chuàng)建新的頁(yè)面,而只是會(huì)返回一個(gè)標(biāo)識(shí)該內(nèi)存塊的標(biāo)識(shí)符。一個(gè)進(jìn)程如需使用這個(gè)共享內(nèi)存塊,則首先需要將它綁定到自己的地址空間中。這樣會(huì)創(chuàng)建一個(gè)從進(jìn)程本身虛擬地址到共享頁(yè)面的映射關(guān)系。當(dāng)對(duì)共享內(nèi)存的使用結(jié)束之后,這個(gè)映射關(guān)系將被刪除。當(dāng)再也沒(méi)有進(jìn)程需要使用這個(gè)共享內(nèi)存塊的時(shí)候,必須有一個(gè)(且只能是一個(gè))進(jìn)程負(fù)責(zé)釋放這個(gè)被共享的內(nèi)存頁(yè)面。

所有共享內(nèi)存塊的大小都必須是系統(tǒng)頁(yè)面大小的整數(shù)倍。系統(tǒng)頁(yè)面大小指的是系統(tǒng)中單個(gè)內(nèi)存頁(yè)面包含的字節(jié)數(shù)。在 Linux 系統(tǒng)中,內(nèi)存頁(yè)面大小是4KB,不過(guò)您仍然應(yīng)該通過(guò)調(diào)用 getpagesize 獲取這個(gè)值。

分配

進(jìn)程通過(guò)調(diào)用shmget(Shared Memory GET,獲取共享內(nèi)存)來(lái)分配一個(gè)共享內(nèi)存塊。

該函數(shù)的第一個(gè)參數(shù)是一個(gè)用來(lái)標(biāo)識(shí)共享內(nèi)存塊的鍵值。彼此無(wú)關(guān)的進(jìn)程可以通過(guò)指定同一個(gè)鍵以獲取對(duì)同一個(gè)共享內(nèi)存塊的訪問(wèn)。不幸的是,其它程序也可能挑選了同樣的特定值作為自己分配共享內(nèi)存的鍵值,從而產(chǎn)生沖突。用特殊常量IPC_PRIVATE作為鍵值可以保證系統(tǒng)建立一個(gè)全新的共享內(nèi)存塊。

該函數(shù)的第二個(gè)參數(shù)指定了所申請(qǐng)的內(nèi)存塊的大小。因?yàn)檫@些內(nèi)存塊是以頁(yè)面為單位進(jìn)行分配的,實(shí)際分配的內(nèi)存塊大小將被擴(kuò)大到頁(yè)面大小的整數(shù)倍。

第三個(gè)參數(shù)是一組標(biāo)志,通過(guò)特定常量的按位或操作來(lái)shmget。這些特定常量包括:

IPC_CREAT:這個(gè)標(biāo)志表示應(yīng)創(chuàng)建一個(gè)新的共享內(nèi)存塊。通過(guò)指定這個(gè)標(biāo)志,我們可以創(chuàng)建一個(gè)具有指定鍵值的新共享內(nèi)存塊。

IPC_EXCL:這個(gè)標(biāo)志只能與 IPC_CREAT 同時(shí)使用。當(dāng)指定這個(gè)標(biāo)志的時(shí)候,如果已有一個(gè)具有這個(gè)鍵值的共享內(nèi)存塊存在,則shmget會(huì)調(diào)用失敗。也就是說(shuō),這個(gè)標(biāo)志將使線程獲得一個(gè)“獨(dú)有”的共享內(nèi)存塊。如果沒(méi)有指定這個(gè)標(biāo)志而系統(tǒng)中存在一個(gè)具有相同鍵值的共享內(nèi)存塊,shmget會(huì)返回這個(gè)已經(jīng)建立的共享內(nèi)存塊,而不是重新創(chuàng)建一個(gè)。

模式標(biāo)志:這個(gè)值由9個(gè)位組成,分別表示屬主、屬組和其它用戶對(duì)該內(nèi)存塊的訪問(wèn)權(quán)限。其中表示執(zhí)行權(quán)限的位將被忽略。指明訪問(wèn)權(quán)限的一個(gè)簡(jiǎn)單辦法是利用<sys/stat.h>中指定,并且在手冊(cè)頁(yè)第二節(jié)stat條目中說(shuō)明了的常量指定。例如,S_IRUSR和S_IWUSR分別指定了該內(nèi)存塊屬主的讀寫權(quán)限,而 S_IROTH和S_IWOTH則指定了其它用戶的讀寫權(quán)限。 下面例子中shmget函數(shù)創(chuàng)建了一個(gè)新的共享內(nèi)存塊(當(dāng)shm_key已被占用時(shí)則獲取對(duì)一個(gè)已經(jīng)存在共享內(nèi)存塊的訪問(wèn)),且只有屬主對(duì)該內(nèi)存塊具有讀寫權(quán)限,其它用戶不可讀寫。

int segment_id = shmget (shm_key, getpagesize (), IPC_CREAT | S_IRUSR| S_IWUSR ); 如果調(diào)用成功,shmget將返回一個(gè)共享內(nèi)存標(biāo)識(shí)符。如果該共享內(nèi)存塊已經(jīng)存在,系統(tǒng)會(huì)檢查訪問(wèn)權(quán)限,同時(shí)會(huì)檢查該內(nèi)存塊是否被標(biāo)記為等待摧毀狀態(tài)。

綁定脫離

要讓一個(gè)進(jìn)程獲取對(duì)一塊共享內(nèi)存的訪問(wèn),這個(gè)進(jìn)程必須先調(diào)用 shmat(SHared Memory Attach,綁定到共享內(nèi)存)。將 shmget 返回的共享內(nèi)存標(biāo)識(shí)符 SHMID 傳遞給這個(gè)函數(shù)作為第一個(gè)參數(shù)。該函數(shù)的第二個(gè)參數(shù)是一個(gè)指針,指向您希望用于映射該共享內(nèi)存塊的進(jìn)程內(nèi)存地址;如果您指定NULL則Linux會(huì)自動(dòng)選擇一個(gè)合適的地址用于映射。第三個(gè)參數(shù)是一個(gè)標(biāo)志位,包含了以下選項(xiàng):

SHM_RND表示第二個(gè)參數(shù)指定的地址應(yīng)被向下靠攏到內(nèi)存頁(yè)面大小的整數(shù)倍。如果您不指定這個(gè)標(biāo)志,您將不得不在調(diào)用shmat的時(shí)候手工將共享內(nèi)存塊的大小按頁(yè)面大小對(duì)齊。 SHM_RDONLY表示這個(gè)內(nèi)存塊將僅允許讀取操作而禁止寫入。 如果這個(gè)函數(shù)調(diào)用成功則會(huì)返回綁定的共享內(nèi)存塊對(duì)應(yīng)的地址。通過(guò) fork 函數(shù)創(chuàng)建的子進(jìn)程同時(shí)繼承這些共享內(nèi)存塊;如果需要,它們可以主動(dòng)脫離這些共享內(nèi)存塊。 當(dāng)一個(gè)進(jìn)程不再使用一個(gè)共享內(nèi)存塊的時(shí)候應(yīng)通過(guò)調(diào)用 shmdt(Shared Memory Detach,脫離共享內(nèi)存塊)函數(shù)與該共享內(nèi)存塊脫離。將由 shmat 函數(shù)返回的地址傳遞給這個(gè)函數(shù)。如果當(dāng)釋放這個(gè)內(nèi)存塊的進(jìn)程是最后一個(gè)使用該內(nèi)存塊的進(jìn)程,則這個(gè)內(nèi)存塊將被刪除。對(duì) exit 或任何exec族函數(shù)的調(diào)用都會(huì)自動(dòng)使進(jìn)程脫離共享內(nèi)存塊。

控制釋放

調(diào)用 shmctl("Shared Memory Control",控制共享內(nèi)存)函數(shù)會(huì)返回一個(gè)共享內(nèi)存塊的相關(guān)信息。同時(shí) shmctl 允許程序修改這些信息。該函數(shù)的第一個(gè)參數(shù)是一個(gè)共享內(nèi)存塊標(biāo)識(shí)。

要獲取一個(gè)共享內(nèi)存塊的相關(guān)信息,則為該函數(shù)傳遞 IPC_STAT 作為第二個(gè)參數(shù),同時(shí)傳遞一個(gè)指向一個(gè) struct shmid_ds 對(duì)象的指針作為第三個(gè)參數(shù)。

要?jiǎng)h除一個(gè)共享內(nèi)存塊,則應(yīng)將 IPC_RMID 作為第二個(gè)參數(shù),而將 NULL 作為第三個(gè)參數(shù)。當(dāng)最后一個(gè)綁定該共享內(nèi)存塊的進(jìn)程與其脫離時(shí),該共享內(nèi)存塊將被刪除。

您應(yīng)當(dāng)在結(jié)束使用每個(gè)共享內(nèi)存塊的時(shí)候都使用 shmctl 進(jìn)行釋放,以防止超過(guò)系統(tǒng)所允許的共享內(nèi)存塊的總數(shù)限制。調(diào)用 exit 和 exec 會(huì)使進(jìn)程脫離共享內(nèi)存塊,但不會(huì)刪除這個(gè)內(nèi)存塊。 要查看其它有關(guān)共享內(nèi)存塊的操作的描述,請(qǐng)參考shmctl函數(shù)的手冊(cè)頁(yè)。

優(yōu)點(diǎn)缺點(diǎn)

共享內(nèi)存塊提供了在任意數(shù)量的進(jìn)程之間進(jìn)行高效雙向通信的機(jī)制。每個(gè)使用者都可以讀取寫入數(shù)據(jù),但是所有程序之間必須達(dá)成并遵守一定的協(xié)議,以防止諸如在讀取信息之前覆寫內(nèi)存空間等競(jìng)爭(zhēng)狀態(tài)的出現(xiàn)。不幸的是,Linux無(wú)法嚴(yán)格保證提供對(duì)共享內(nèi)存塊的獨(dú)占訪問(wèn),甚至是在您通過(guò)使用IPC_PRIVATE創(chuàng)建新的共享內(nèi)存塊的時(shí)候也不能保證訪問(wèn)的獨(dú)占性。 同時(shí),多個(gè)使用共享內(nèi)存塊的進(jìn)程之間必須協(xié)調(diào)使用同一個(gè)鍵值。

共享內(nèi)存才是實(shí)現(xiàn)進(jìn)程間通信最簡(jiǎn)單也是最直接的方法

 

分享到:
標(biāo)簽:內(nèi)存 共享
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定