Linux共用記憶體實踐(1)

來源:互聯網
上載者:User

標籤:linux   ipc   共用記憶體   處理序間通訊   進階編程   

共用記憶體基本概念

    共用記憶體區是最快的IPC形式。一旦這樣的記憶體映射到共用它的進程的地址空間,這些進程間資料傳遞不再涉及到核心,換句話說是進程不再通過執行進入核心的系統調用來傳遞彼此的資料()。


 

共用記憶體 VS. 其他IPC形式

    用管道/訊息佇列傳遞資料

 

 

 

    用共用記憶體傳遞資料

 


(核心為每個IPC對象維護一個資料結構)

    共用記憶體產生之後,傳遞資料並不需要再走Linux核心,共用記憶體允許兩個或多個進程共用一個給定的儲存地區,資料並不需要在多個進程之間進行複製,因此,共用記憶體的傳輸速度更快!!

 

System V共用記憶體資料結構與基本API
//基本資料結構struct shmid_ds{    struct ipc_perm shm_perm;    /* Ownership and permissions */    size_t          shm_segsz;   /* Size of segment (bytes) */    time_t          shm_atime;   /* Last attach time */    time_t          shm_dtime;   /* Last detach time */    time_t          shm_ctime;   /* Last change time */    pid_t           shm_cpid;    /* PID of creator */    pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */    shmatt_t        shm_nattch;  /* No. of current attaches */    ...};

共用記憶體函數 

#include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);void *shmat(int shmid, const void *shmaddr, int shmflg);int shmdt(const void *shmaddr);int shmctl(int shmid, int cmd, struct shmid_ds *buf);

 

shmget函數

功能:建立共用記憶體,並將該記憶體的內容初始化為0

原型:

int shmget(key_t key, size_t size, int shmflg);

參數:

    key:這個共用記憶體段名字

    size:共用記憶體大小

    shmflg:由九個許可權標誌構成,它們的用法和建立檔案時使用的mode模式標誌是一樣的

 

傳回值:

    成功返回一個非負整數,即該共用記憶體段的標識碼;失敗返回-1

//實驗1:開啟已經存在的共用記憶體int main(){  // int shmget(key_t key, size_t size, int shmflg);  //開啟已經存在的共用記憶體    int shmid = shmget(0x225,1024,0666);    if (shmid == -1)    {        if (errno == ENOENT)        {            cout << "ENOENT = " << errno << endl;        }        err_exit("shmget error");    }    return 0;}

//實驗2:共用記憶體如若存在,則直接使用;若不存在,則建立. [IPC_CREAT選項作用]int main(){    // int shmget(key_t key, size_t size, int shmflg);    int shmid = shmget(0x225,1024,0666|IPC_CREAT);    if (shmid == -1)    {        if (errno == ENOENT)        {            cout << "ENOENT = " << errno << endl;        }        err_exit("shmget error");    }    else    {        cout << "shmid = " << shmid << endl;    }    return 0;}

//實驗3:共用記憶體如果沒有,則建立;如果存在,則返回錯誤. [IPC_CREAT|IPC_EXCL組合作用]int main(){    // int shmget(key_t key, size_t size, int shmflg);    int shmid = shmget(0x225,1024,0666|IPC_CREAT|IPC_EXCL);    if (shmid == -1)    {        if (errno == ENOENT)        {            cout << "ENOENT = " << errno << endl;        }        else if (errno == EEXIST)        {            cout << "File is exits... EEXIST = " << errno << endl;        }        err_exit("shmget error");    }    else    {        cout << "shmid = " << shmid << endl;    }    return 0;}

 

 

shmat函數

功能:將共用記憶體段串連到進程地址空間

原型:

void *shmat(int shmid, const void *shmaddr, int shmflg);

參數:

    shmid: 共用記憶體標識

    shmaddr:指定串連的地址

    shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY

 

傳回值:

    成功返回一個指標,指向共用記憶體第一個節;失敗返回-1

 

Shmaddr與shmflg組合說明

    shmaddr為NULL,Linux內和將自動為進程串連到該記憶體(推薦使用)

    shmaddr不為NULL且shmflg無SHM_RND標記,則以shmaddr為串連地址。

    shmaddr不為NULL且shmflg設定了SHM_RND標記,則串連的地址會自動向下調整為SHMLBA的整數倍。公式:shmaddr - (shmaddr % SHMLBA)

    shmflg=SHM_RDONLY,表示串連操作用來唯讀共用記憶體


//樣本1int main(){    // int shmget(key_t key, size_t size, int shmflg);    //擷取或者開啟共用記憶體    int shmid = shmget(0x1576422, sizeof(Student), 0666 | IPC_CREAT);    if (shmid == -1)    {        err_exit("shmget error");    }    //將ID為shmid的共用記憶體串連到該進程    Student *pStudent = static_cast<Student *>(shmat(shmid, NULL, 0));    //向記憶體中寫入資料    Student studentA = {"xiaofang",2012};    memcpy(pStudent,&studentA,sizeof(Student));    cout << pStudent ->name << " " << pStudent ->number << endl;    //亦可擷取該記憶體內容(其實跟本地記憶體沒有什麼區別)    Student *pNewStudent = pStudent;    cout << pNewStudent -> name << " " << pNewStudent -> number << endl;    return 0;}

//樣本2:將共用記憶體當成數組int main(){    // int shmget(key_t key, size_t size, int shmflg);    //擷取或者開啟共用記憶體    int shmid = shmget(0x15764221, 1024 * sizeof(int), 0666 | IPC_CREAT);    if (shmid == -1)    {        err_exit("shmget error");    }    //將ID為shmid的共用記憶體串連到該進程    int *pArray = static_cast<int *>(shmat(shmid, NULL, 0));    if (pArray == (void *)-1)    {        err_exit("shmat error");    }    for (int i = 0; i != 1024; ++i)    {        pArray[i] = i+1;    }    for (int i = 0; i != 1024; ++i)    {        cout << pArray[i] << endl;    }    return 0;}


Linux共用記憶體實踐(1)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.