Linux進程間通信之共享內存


一,共享內存
  內核管理一片物理內存,允許不同的進程同時映射,多個進程可以映射同一塊內存,被多個進程同時映射的物理內存,即共享內存。
  映射物理內存叫掛接,用完以后解除映射叫脫接

1,共享內存的特點:

  優點:是最快的IPC。
  缺點:要編程者自己實現對共享內存互斥訪問。如何實現?

2,編程模型:具體函數的用法可以用man手冊查看(強力推薦)

進程A: writeshm.c
     1) 獲得key, ftok()
     2) 使用key來創建一個共享內存 shmget()
     3) 映射共享內存(得到虛擬地址), shmat()
     4) 使用共享內存, 往共享內存中寫入數據
     5) 解除映射 shmdt()
     6) 如果共享內存不再使用,可以使用shmctl()銷毀共享內存

 

進程B: readshm.c     

  1) 獲得key, ftok()     

  2) 使用key來獲得一個共享內存 shmget()     

  3) 映射共享內存(得到虛擬地址), shmat()     

  4) 使用共享內存, 讀取共享內存中的數據     

  5) 解除映射 shmdt()     

 

3,實例

進程A:

// writeshm.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main()
{
    // 生成一個key
    key_t key = ftok("./", 66);

    // 創建共享內存,返回一個id
    int shmid = shmget(key, 8, IPC_CREAT|0666|IPC_EXCL);
    if(-1 == shmid)
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享內存,得到虛擬地址
    void *p = shmat(shmid, 0, 0);
    if((void*)-1 == p)
    {
        perror("shmat failed");
        exit(2);
    }

    // 寫共享內存
    int *pp = p;
    *pp = 0x12345678;
    *(pp + 1) = 0xffffffff;

    // 解除映射
    if(-1 == shmdt(p))
    {
        perror("shmdt failed");
        exit(3);
    }
    printf("解除映射成功,點擊回車銷毀共享內存\n");
    getchar();

    // 銷毀共享內存
    if(-1 == shmctl(shmid, IPC_RMID, NULL))
    {
        perror("shmctl failed");
        exit(4);
    }

    return 0;
}


進程B:

// readshm.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main()
{
    // 生成一個key
    key_t key = ftok("./", 66);

    // 獲取共享內存,返回一個id
    int shmid = shmget(key, 0, 0);
    if(-1 == shmid)
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享內存,得到虛擬地址
    void *p = shmat(shmid, 0, 0);
    if((void*)-1 == p)
    {
        perror("shmat failed");
        exit(2);
    }

    // 讀共享內存
    int x = *(int *)p;
    int y = *((int *)p + 1);
    printf("從共享內存中都取了:0x%x 和 0x%x \n", x, y);

    // 解除映射
    if(-1 == shmdt(p))
    {
        perror("shmdt failed");
        exit(3);
    }

    return 0;
}

 運行結果:

writeshma:

readshma:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM