• 當前位置:首頁 > IT技術 > 系統服務 > 正文

    進程間通信 共享內存
    2021-11-16 11:30:32


    進程間通信 共享內存_#include



    共享內存指 (shared memory)在多處理器的計算機系統中,可以被不同中央處理器(CPU)訪問的大容量內存。--百度百科

    上述已經將共享內存的概念說的很清晰了,簡單理解就是多個進程可共用一片存儲內存。

    Linux已經提供了共享內存的接口,本文主要簡單介紹此接口使用方法及使用實例。

    接口說明

    設置共享存儲標識符:

    設定共享內存的標識符,用于讀寫時唯一許可。

    /**
    * @brief: returns the identifier of the System V shared memory
    * segment associated with the value of the argument key.
    *
    * @param - key: identification of the IPC
    * @param - size: the size of shared memory usage
    * @param - shmflg: If shmflg specifies both IPC_CREAT and IPC_EXCL
    * and a shared memory segment already exists for key, then shmget()
    * fails with errno set to EEXIST.
    *
    * @return On success, a valid shared memory identifier is returned.
    * On error, -1 is returned, and errno is set to indicate the error.
    */int shmat(key_t key, size_t size, int shmflg)


    將共享字段鏈接到地址空間

    設定共享內存字段在系統的存儲地址。

    /**
    * @brief: shmat() attaches the System V shared memory segment
    * identified by shmid to the address space of the calling process.
    *
    * @param - shmid:
    * @param - shmaddr: the addr of the System V shared memory
    * @param - shmflg:
    *
    * @return On success, shmat() returns the address of the attached
    * shared memory segment;
    * on error, (void *) -1 is returned, and errno is set to indicate
    * the cause of the error.
    */void *shmat(int shmid, const void *shmaddr, int shmflg)


    取消共享地址映射

    當共享內存使用完畢后,調此接口會結束共享內存與指定的系統地址的映射關系。這里并未從系統中刪除標識符,該標識符一直存在直至某個進程帶IPC_RMID命令調用shmctl特地刪除它為止。

    /**
    * @brief: detaches the shared memory segment located at the
    * address specified by shmaddr from the address space of the calling
    * process.
    *
    * @param - shmaddr: the addr of the System V shared memory
    *
    * @return On success, shmdt() returns 0;
    * on error -1 is returned, and errno is set to indicate the cause of
    * the error.
    */int shmdt(const void *shmaddr);


    共享內存多種操作

    類似于驅動ctrl函數,即傳入不同的命令可執行不同的操作。cmd可選擇IPC_STAT/IPC_SET/IPC_RMID/SHM_LOCK/SHM_UNLOCK。

    IPC_STAT 將與shmid關聯的內核數據結構中的信息復制到buf所指向的shmid_ds結構中。

    IPC_SET 將buf指向的shmid_ds結構的一些成員的值寫入與這個共享內存段相關聯的內核數據結構,同時更新它的shm_ctime成員。

    IPC_RMID 標記要銷毀的共享內存。只有在最后一個進程將它分離之后,共享內存才會被銷毀。

    SHM_LOCK 防止讀取共享內存。

    SHM_UNLOCK 解鎖共享內存,允許它被讀取出來。

    /**
    * @brief: performs the control operation specified by cmd on the
    * System V shared memory segment whose identifier is given in shmid.
    *
    * @param - shmid:
    * @param - cmd:
    * @param - buf:
    *
    * @return A successful IPC_INFO or SHM_INFO operation returns the
    * index of the highest used entry in the kernel's internal array recording
    * information about all shared memory segments. (This information
    * can be used with repeated SHM_STAT or SHM_STAT_ANY operations
    * to obtain information about all shared memory segments on the system.)
    * A successful SHM_STAT operation returns the identifier of the shared
    * memory segment whose index was given in shmid. Other operations
    * return 0 on success.
    * On error, -1 is returned, and errno is set appropriately.
    */int shmctl(int shmid, int cmd, struct shmid_ds *buf)


    實例演示

    功能: 使用共享內存設計兩個讀寫進程,實現跨進程通信。演示:進程間通信 共享內存_共享內存_02

    總結

    本文主要接收共享內存接口的簡單使用實例,其可通過shmctl傳輸不同的指令實現比較高級的用法,例如權限限制。其中共享內存也可以配合其他機制實現一套比較好用的通信策略,后續可以玩一玩。

    代碼

    read.cpp

    #include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/shm.h>#include "common.h"
    int main(int argc, char *argv[]){ int shmid, running = 1; void *shm = NULL; struct ShmData *pShareData = NULL;
    shmid = shmget((key_t)SHM_NAME, sizeof(struct ShmData), 0666|IPC_CREAT); if (shmid == -1) { printf("shmget failed! "); exit(0); }
    shm = shmat(shmid, 0, 0); if (shm == (void*)-1) { printf("shmat failed! "); exit(0); } printf("Memory attached at %p ", shm);
    pShareData = (struct ShmData *)shm; pShareData->flag = 0;
    while (running) { if (pShareData->flag) { printf("The memery data: %s", pShareData->data); sleep(rand() % 3); pShareData->flag = 0;
    if (!strncmp(pShareData->data, "end", 3)) { running = 0; }
    } else { sleep(1); } }
    printf("Over! "); if (shmdt(shm) == -1) { printf("shmdt failed! "); exit(0); }
    if (shmctl(shmid, IPC_RMID, 0) == -1) { printf("shmctl failed! "); exit(0); }
    return 0;}


    write.cpp

    #include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/shm.h>#include "common.h"
    int main(int argc, char *argv[]){ int shmid, running = 1; char buffer[DATA_SIZE+1] = {0}; void *shm = NULL; struct ShmData *pShareData = NULL;
    shmid = shmget((key_t)SHM_NAME, sizeof(struct ShmData), IPC_EXCL); if (shmid == -1) { printf("shmget failed! "); exit(0); }
    shm = shmat(shmid, (void*)0, 0); if (shm == (void*)-1) { printf("shmat failed! "); exit(0); } printf("Memory attached at %p ", shm);
    pShareData = (struct ShmData *)shm; //pShareData->flag = 0;
    while (running) { while (pShareData->flag == 1) { sleep(1); printf("Waiting... "); }
    printf("Input data: "); fgets(buffer, DATA_SIZE, stdin); strncpy(pShareData->data, buffer, DATA_SIZE); pShareData->flag = 1;
    if (strncmp(buffer, "end", 3) == 0) { running = 0; } }
    if (shmdt(shm) == -1) { printf("shmdt failed! "); exit(0); } sleep(2);
    return 0;}




    最后

    用心感悟,認真記錄,寫好每一篇文章,分享每一框干貨。愿每一篇文章不負自己,不負看客!


    更多文章內容包括但不限于C/C++、Linux、開發常用神器等,可進入開源519公眾號聊天界面回復“文章目錄” 或者 菜單欄選擇“文章目錄”查看。

    進程間通信 共享內存_標識符_03



    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码