LINUX處理序間通訊之共用儲存講解,linux進程通訊講解

來源:互聯網
上載者:User

LINUX處理序間通訊之共用儲存講解,linux進程通訊講解
LINUX處理序間通訊一、匿名管道與具名管道二、訊息佇列三、共用儲存

共用儲存概述:共用儲存允許兩個或更多進程共用一給定的儲存區。共用記憶體區是最快的IPC形式,一旦這樣的記憶體映射到共用它的進程的 地址空間,這些進程間資料傳遞不再涉及到核心,也就是說進程不再需要切換到核心態來傳遞資料。所以比起訊息佇列一直在使用者態和核心態的切換,共用儲存更高效。相關命令:

ipcs -m :查看當前核心中的共用記憶體段;
ipcrm -m +shmid :刪除對應shmid的共用記憶體段

共用記憶體:

也就是說:進程同時拿到同一片共用儲存區的shmid,使用shmat將對應的共用儲存空間串連到自己的進程地址空間,在進行操作完成之後,再使用shmdt中斷連線。在整體使用過程中不需要多次進行狀態切換。共用記憶體資料結構:

函數介紹:一、shmget:獲得共用儲存標識符
       #include        #include        int shmget(key_t key, size_t size, int shmflg);//傳回值:成功返回共用記憶體的標識符,失敗返回-1
參數介紹:①key:與訊息佇列相同,都是由ftok函數產生;②size:共用記憶體大小(單位/位元組);通常將其向上取為系統頁長的整數倍;③shmflg:用法和建立檔案使用的mode模式標誌一樣。可參考訊息佇列中的介紹。二、shmctl: 控制共用記憶體
  #include        #include        int shmctl(int shmid, int cmd, struct shmid_ds *buf);//成功返回0,失敗返回-1
參數介紹:①shmid:需要進行操作的共用記憶體標識碼;②cmd:需要進行的操作(分為IPC_STAT,IPC_SET,IPC_RMID)③buf:一個指向shmid_ds結構體類型的結構體指標,當參數為IPC_STAT和IPC_SET時,需要給定一個結構體,用來指定修改的值。三、shmat:將共用記憶體段串連到進程地址空間
  #include        #include        void *shmat(int shmid, const void *shmaddr, int shmflg);//傳回值:成功返回指向共用記憶體第一個位元組的指標,失敗返回-1
參數介紹:①shmid:之前由ftok產生的共用記憶體標識符;②shmaddr:指定串連的地址;③shmflg:可取SHM_RND和SHM_RDONLY
shmaddr取值為NULL,核心自動選擇一個地址shmaddr不為NULL,且shmflg無SHM_RND標記,則以shmaddr為串連地址;shmaddr不為NULL,且shmflg設定了SHM_RND標記,則串連的地址會自動向下調整為SHMLBA的整數倍shmflg = SHM_RDONLY:表示串連操作用來唯讀共用記憶體。
註:更詳細的介紹可自行man或查看《unix環境進階編程》四、shmdt:將共用記憶體段與當前進程脫離
  #include        #include        void *shmat(int shmid, const void *shmaddr, int shmflg);       int shmdt(const void *shmaddr);//傳回值:成功返回0,失敗返回-1
參數介紹:shmaddr:由shmat所返回的指標。注意:1、共用記憶體無同步互斥機制!!2、共用記憶體段隨核心,所以我們最好是在進程結束之前不再使用時,就斷開與共用記憶體的串連。樣本:通過一片共用記憶體儲存區,client向其中寫資料,server讀取資料並列印到螢幕上。
/**********comm.h*************/#pragma once#include #include #include #include #define PATHNAME "."#define PROJ_ID 0x66int createShm(int size);int destroyShm(int shmid);int getShm(int size);/**********comm.c**********/#include "comm.h"int commShm(int size, int flags){    key_t key = ftok(PATHNAME, PROJ_ID);    if(key < 0){        perror("ftok");        return -1;    }    int shmid = shmget(key, size, flags);    if(shmid < 0){        perror("shmget");        return -2;    }    return shmid;}int destroyShm(int shmid){    if(shmctl(shmid, IPC_RMID, NULL) < 0){        perror("shmctl");        return -1;    }    return 0;}int creatShm(int size){    return commShm(size, IPC_CREAT | IPC_EXCL | 0666);}int getShm(int size){    return commShm(size, IPC_CREAT);}/**********client.c********/#include "comm.h"int main(){    int shmid = getShm(4094);    char* addr = shmat(shmid, NULL, 0);    sleep(1);    int i = 0;    while(i < 5){        addr[i] = 'A' +i;        i++;        addr[i] = 0;        sleep(1);    }    shmdt(addr);    sleep(2);    return 0;}/*********server.c*******/#include "comm.h"int main(){    int shmid = creatShm(4096);    char* addr = (char*)shmat(shmid, NULL, 0);    sleep(5);    int i = 0;    while(i < 10){        i++;        printf("client> %s\n",addr);        sleep(1);    }    shmdt(addr);    sleep(2);    destroyShm(shmid);    return 0;}/*******Makefile********/.PHONY : allall : server clientserver : server.c comm.c    gcc $^ -o $@client : client.c comm.c    gcc $^ -o $@.PHONY : cleanclean:    rm server client
運行結果:開啟server端,再開啟client端,經過sleep後,client端向共用記憶體中寫入資料,server端不斷讀取,但是當client端停止寫入時,共用記憶體區的資料還是最後一次寫入的資料,所以又多輸出5次。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.