• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開心的工作
            簡單、開放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            linux 共享內(nèi)存的使用

            Posted on 2012-01-02 23:36 S.l.e!ep.¢% 閱讀(2275) 評論(0)  編輯 收藏 引用 所屬分類: Unix

            使用共享內(nèi)存的目的:
            ?共享內(nèi)存共享內(nèi)存是進(jìn)程間通信中最簡單的方式之一。
            ?共享內(nèi)存允許兩個(gè)或更多進(jìn)程訪問同一塊內(nèi)存,就如同 malloc() 函數(shù)向不同進(jìn)程返回了指向同一個(gè)物理內(nèi)存區(qū)域的指針。
            ?當(dāng)一個(gè)進(jìn)程改變了這塊地址中的內(nèi)容的時(shí)候,其它進(jìn)程都會(huì)察覺到這個(gè)更改。
            使用共享內(nèi)存的流程:
            ?1.進(jìn)程必須首先分配它。
            ?2.隨后需要訪問這個(gè)共享內(nèi)存塊的每一個(gè)進(jìn)程都必須將這個(gè)共享內(nèi)存綁定到自己的地址空間中。
            ?3.當(dāng)完成通信之后,所有進(jìn)程都將脫離共享內(nèi)存,并且由一個(gè)進(jìn)程釋放該共享內(nèi)存塊。
            分配:
            ?int segment_id = shmget (shm_key, int size , shmflag );
            ?1.進(jìn)程通過調(diào)用shmget(Shared Memory GET,獲取共享內(nèi)存)來分配一個(gè)共享內(nèi)存塊。 該函數(shù)的第一個(gè)參數(shù)是一個(gè)用來標(biāo)識(shí)共享內(nèi)存塊的鍵值。
            ?彼此無關(guān)的進(jìn)程可以通過指定同一個(gè)鍵以獲取對同一個(gè)共享內(nèi)存塊的訪問。
            ?不幸的是,其它程序也可能挑選了同樣的特定值作為自己分配共享內(nèi)存的鍵值,從而產(chǎn)生沖突。
            ?用特殊常量IPC_PRIVATE作為鍵值可以保證系統(tǒng)建立一個(gè)全新的共享內(nèi)存塊。
            ?2.該函數(shù)的第二個(gè)參數(shù)指定了所申請的內(nèi)存塊的大小。
            ?因?yàn)檫@些內(nèi)存塊是以頁面為單位進(jìn)行分配的,實(shí)際分配的內(nèi)存塊大小將被擴(kuò)大到頁面大小的整數(shù)倍。
            ?3.第三個(gè)參數(shù)是一組標(biāo)志,通過特定常量的按位或操作來shmget。這些特定常量包括:
            ?IPC_CREAT:
            ??這個(gè)標(biāo)志表示應(yīng)創(chuàng)建一個(gè)新的共享內(nèi)存塊。通過指定這個(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)用失敗。
            ??也就是說,這個(gè)標(biāo)志將使線程獲得一個(gè)“獨(dú)有”的共享內(nèi)存塊。如果沒有指定這個(gè)標(biāo)志而系統(tǒng)中存在一個(gè)具有相通鍵值的共享內(nèi)存塊,
            ??shmget會(huì)返回這個(gè)已經(jīng)建立的共享內(nèi)存塊,而不是重新創(chuàng)建一個(gè)。
            ?模式標(biāo)志:
            ??這個(gè)值由9個(gè)位組成,分別表示屬主、屬組和其它用戶對該內(nèi)存塊的訪問權(quán)限。其中表示執(zhí)行權(quán)限的位將被忽略。
            ??指明訪問權(quán)限的一個(gè)簡單辦法是利用<sys/stat.h>中指定,并且在手冊頁第二節(jié)stat條目中說明了的常量指定。
            ??例如,
            ???S_IRUSR和S_IWUSR分別指定了該內(nèi)存塊屬主的讀寫權(quán)限,
            ???S_IROTH和S_IWOTH則指定了其它用戶的讀寫權(quán)限。
            綁定和脫離:
            ?pst= shmat(iShm_id, NULL, 0)
            ?一個(gè)進(jìn)程獲取對一塊共享內(nèi)存的訪問,這個(gè)進(jìn)程必須先調(diào)用 shmat(SHared Memory Attach,綁定到共享內(nèi)存)。
            ?將 shmget 返回的共享內(nèi)存標(biāo)識(shí)符 SHMID 傳遞給這個(gè)函數(shù)作為第一個(gè)參數(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)存頁面大小的整數(shù)倍。
            ???如果您不指定這個(gè)標(biāo)志,您將不得不在調(diào)用shmat的時(shí)候手工將共享內(nèi)存塊的大小按頁面大小對齊。
            ??SHM_RDONLY
            ???表示這個(gè)內(nèi)存塊將僅允許讀取操作而禁止寫入。 如果這個(gè)函數(shù)調(diào)用成功則會(huì)返回綁定的共享內(nèi)存塊對應(yīng)的地址。
            ???通過 fork 函數(shù)創(chuàng)建的子進(jìn)程同時(shí)繼承這些共享內(nèi)存塊;
            ???如果需要,它們可以主動(dòng)脫離這些共享內(nèi)存塊。
            ???當(dāng)一個(gè)進(jìn)程不再使用一個(gè)共享內(nèi)存塊的時(shí)候應(yīng)通過調(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)存塊將被刪除。
            ???對 exit 或任何exec族函數(shù)的調(diào)用都會(huì)自動(dòng)使進(jìn)程脫離共享內(nèi)存塊。
            控制和釋放共享內(nèi)存塊:
            ?shmctl(iShm_id,IPC_RMID,0)<0
            ?調(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 對象的指針作為第三個(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)行釋放,以防止超過系統(tǒng)所允許的共享內(nèi)存塊的總數(shù)限制。調(diào)用 exit 和 exec 會(huì)使進(jìn)程脫離共享內(nèi)存塊,
            ?但不會(huì)刪除這個(gè)內(nèi)存塊。 要查看其它有關(guān)共享內(nèi)存塊的操作的描述,請參考shmctl函數(shù)的手冊頁。

            共享內(nèi)存的總體大小是有限制的,這個(gè)大小通過SHMMAX參數(shù)來定義(以字節(jié)為單位),
            您可以通過執(zhí)行以下命令來確定 SHMMAX 的值:
            cat /proc/sys/kernel/shmmax

            修改共享內(nèi)存:
            ?設(shè)置 SHMMAX
            ?# >echo "2147483648" > /proc/sys/kernel/shmmax
            ?您還可以使用 sysctl 命令來更改 SHMMAX 的值:
            ?# sysctl -w kernel.shmmax=2147483648
            ?最后,通過將該內(nèi)核參數(shù)插入到 /etc/sysctl.conf 啟動(dòng)文件中,您可以使這種更改永久有效:
            ?# echo "kernel.shmmax=2147483648" >> /etc/sysctl.conf
            ====================================================================

            /*********************************************************
            ?*? filename:?ipc.c
            ?*? author:?wjy
            ?*? date:?20110509
            *********************************************************/
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <errno.h>
            #include <unistd.h>
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/shm.h>
            #include <sys/stat.h>
            int main(int argc,char *argv[])
            {
            ?key_t shmid;
            ?char *p_addr,*c_addr;
            ?pid_t pid;
            ?if(argc != 2)
            ?{
            ??printf("Usage:program something",argv[0]);
            ??exit(0);
            ?}
            ?if((shmid = shmget(IPC_PRIVATE,1024,S_IRUSR|S_IWUSR)) == -1)
            ?{
            ??printf("create share memory error/n");
            ??exit(1);
            ?}
            ?pid = fork();
            ?if(pid > 0 )
            ?{
            ??p_addr = shmat(shmid,0,0);
            ??memset(p_addr,'/0',1024);
            ??strncpy(p_addr,argv[1],1024);
            ??wait(NULL);
            ?}
            ?else if (pid == 0)
            ?{
            ??sleep(1);
            ??c_addr = shmat(shmid,0,0);
            ??printf("Client get %s/n",c_addr);
            ??exit(0);
            ?}
            ?if(shmctl(shmid,IPC_RMID,0)<0)
            ?{
            ??printf("共享內(nèi)存釋放出錯(cuò)!!/n");
            ??return(-1);
            ?}
            ?else
            ??printf("釋放共享內(nèi)存成功!/n");
            }

            久久青青草原精品国产不卡| 亚洲欧美一区二区三区久久| 久久久久亚洲AV片无码下载蜜桃| 嫩草影院久久国产精品| 久久精品欧美日韩精品| 日本欧美久久久久免费播放网| 日韩欧美亚洲综合久久影院Ds | 伊人色综合久久天天人守人婷 | 久久久久久亚洲精品影院| 久久99精品国产麻豆婷婷| 91麻豆精品国产91久久久久久| 久久精品国产精品国产精品污 | 精品久久久久久无码人妻蜜桃| 99久久精品九九亚洲精品| 国产精品伊人久久伊人电影 | 精品久久久久久国产| 99精品国产99久久久久久97 | 久久久久人妻一区精品果冻| 大美女久久久久久j久久| 国产叼嘿久久精品久久| 久久久久久久综合日本| 午夜精品久久影院蜜桃| 久久天天躁狠狠躁夜夜不卡| 亚洲AV无码一区东京热久久| 精品国产乱码久久久久久1区2区 | 97久久香蕉国产线看观看| 久久久久久综合一区中文字幕 | 国产成人久久激情91| 伊人热人久久中文字幕| 久久夜色精品国产| 中文字幕日本人妻久久久免费| 久久亚洲春色中文字幕久久久| 日本精品久久久久中文字幕| 久久精品人妻一区二区三区| 久久久噜噜噜久久中文字幕色伊伊 | 久久久精品国产亚洲成人满18免费网站| 国内精品欧美久久精品| 久久精品国产亚洲av麻豆图片| 久久久久AV综合网成人| 久久亚洲精品无码观看不卡| 性欧美丰满熟妇XXXX性久久久|