Linux處理序間通訊(System V) --- 共用記憶體

來源:互聯網
上載者:User

Linux處理序間通訊(System V) --- 共用記憶體
共用記憶體 IPC 原理

共用記憶體處理序間通訊機制主要用於實現進程間大量的資料轉送,所示為進程間使用共用記憶體實現大量資料轉送的:

共用記憶體是在記憶體中單獨開闢的一段記憶體空間,這段記憶體空間有自己特有的資料結構,包括存取權限、大小和最近訪問的時間等。該資料結構定義如下:

from /usr/include/linux/shm.hstruct shmid_ds {    struct ipc_perm     shm_perm;   /* operation perms 操作許可權 */    int         shm_segsz;  /* size of segment (bytes) 段長度大小 */    __kernel_time_t     shm_atime;  /* last attach time 最近attach時間 */    __kernel_time_t     shm_dtime;  /* last detach time 最近detach時間 */    __kernel_time_t     shm_ctime;  /* last change time 最近change時間 */    __kernel_ipc_pid_t  shm_cpid;   /* pid of creator 建立者pid */    __kernel_ipc_pid_t  shm_lpid;   /* pid of last operator 最近操作pid */    unsigned short      shm_nattch; /* no. of current attaches */    unsigned short      shm_unused; /* compatibility */    void            *shm_unused2;   /* ditto - used by DIPC */    void            *shm_unused3;   /* unused */};

兩個進程在使用此共用記憶體空間之前,需要在進程地址空間與共用記憶體空間之間建立聯絡,即將共用記憶體空間掛載到進程中。

系統對共用記憶體做了以下限制:

#define SHMMAX 0x2000000         /* max shared seg size (bytes) 最大共用段大小 */#define SHMMIN 1             /* min shared seg size (bytes) 最小共用段大小 */#define SHMMNI 4096          /* max num of segs system wide */#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))#define SHMSEG SHMMNI            /* max shared segs per process */
Linux 共用記憶體管理

1.建立共用記憶體

#include <sys/ipc.h>#include <sys/shm.h>/* * 第一個參數為 key 值,一般由 ftok() 函數產生 * 第二個參數為欲建立的共用記憶體段大小(單位為位元組) * 第三個參數用來標識共用記憶體段的建立標識 */int shmget(key_t key, size_t size, int shmflg);

2.共用記憶體控制

#include <sys/ipc.h>#include <sys/shm.h>/* * 第一個參數為要操作的共用記憶體標識符 * 第二個參數為要執行的操作 * 第三個參數為 shmid_ds 結構的臨時共用記憶體變數資訊 */int shmctl(int shmid, int cmd, struct shmid_ds *buf);

3.映射共用記憶體對象

系統調用 shmat() 函數實現將一個共用記憶體段映射到調用進程的資料區段中,並返回記憶體空間首地址,其函式宣告如下:

#include <sys/types.h>#include <sys/shm.h>/* * 第一個參數為要操作的共用記憶體標識符 * 第二個參數用來指定共用記憶體的映射地址,非0則為此參數,為0的話由系統分配 * 第三個參數用來指定共用記憶體段的存取權限和映射條件 */void *shmat(int shmid, const void *shmaddr, int shmflg);

4.分離共用記憶體對象

在使用完畢共用記憶體空間後,需要使用 shmdt() 函數調用將其與當前進程分離。函式宣告如下:

#include <sys/types.h>#include <sys/shm.h>/* * 參數為分配的共用記憶體首地址 */int shmdt(const void *shmaddr);
共用記憶體在父子進程間遵循的約定
1.使用 fork() 函數建立一個子進程後,該進程繼承父親進程掛載的共用記憶體。2.如果調用 exec() 執行一個新的程式,則所有掛載的共用記憶體將被自動卸載。3.如果在某個進程中調用了 exit() 函數,所有掛載的共用記憶體將與當前進程脫離關係。
程式執行個體

申請一段共用記憶體,父進程在首地址處存入一整數,子進程讀出。

#include <stdio.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#define SHM_SIZE 1024int main(){    int shm_id, pid;    int *ptr = NULL;    /* 申請共用記憶體 */    shm_id = shmget((key_t)1004, SHM_SIZE, IPC_CREAT | 0600);    /* 映射共用記憶體到進程地址空間 */    ptr = (int*)shmat(shm_id, 0, 0);    printf("Attach addr is %p \n", ptr);    *ptr = 1004;    printf("The Value of Parent is : %d \n", *ptr);    if((pid=fork()) == -1){        perror("fork Err");        exit(0);    }    else if(!pid){        printf("The Value of Child is : %d \n", *ptr);        exit(0);    }else{        sleep(1);        /* 解除映射 */        shmdt(ptr);                /* 刪除共用記憶體 */        shmctl(shm_id, IPC_RMID, 0);    }    return 0;}

輸出結果:

相關文章

聯繫我們

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