1. 程式人生 > >c/c++ linux 程序間通訊系列4,使用共享記憶體

c/c++ linux 程序間通訊系列4,使用共享記憶體

linux 程序間通訊系列4,使用共享記憶體

1,建立共享記憶體,用到的函式shmget, shmat, shmdt

函式名 功能描述
shmget 建立共享記憶體,返回pic key
shmat 第一次建立完共享記憶體時,它還不能被任何程序訪問,shmat()函式的作用就是用來啟動對該共享記憶體的訪問,並把共享記憶體連線到當前程序的地址空間
shmdt 該函式用於將共享記憶體從當前程序中分離。注意,將共享記憶體分離並不是刪除它,只是使該共享記憶體對當前程序不再可用。
int shmget(key_t key, size_t size, int shmflg);
  • 第一個引數,與訊號量的semget函式一樣,程式需要提供一個引數key(非0整數),它有效地為共享記憶體段命名,shmget()函式成功時返回一個與key相關的共享記憶體識別符號(非負整數),用於後續的共享記憶體函式。呼叫失敗返回-1.

    不相關的程序可以通過該函式的返回值訪問同一共享記憶體,它代表程式可能要使用的某個資源,程式對所有共享記憶體的訪問都是間接的,程式先通過呼叫shmget()函式並提供一個鍵,再由系統生成一個相應的共享記憶體識別符號(shmget()函式的返回值),只有shmget()函式才直接使用訊號量鍵,所有其他的訊號量函式使用由semget函式返回的訊號量識別符號。

  • 第二個引數,size以位元組為單位指定需要共享的記憶體容量

  • 第三個引數,shmflg是許可權標誌,它的作用與open函式的mode引數一樣,如果要想在key標識的共享記憶體不存在時,建立它的話,可以與IPC_CREAT做或操作。共享記憶體的許可權標誌與檔案的讀寫許可權一樣,舉例來說,0644,它表示允許一個程序建立的共享記憶體被記憶體建立者所擁有的程序向共享記憶體讀取和寫入資料,同時其他使用者建立的程序只能讀取共享記憶體。

void *shmat(int shm_id, const void *shm_addr, int shmflg);
  • 第一個引數,shm_id是由shmget()函式返回的共享記憶體標識。
  • 第二個引數,shm_addr指定共享記憶體連線到當前程序中的地址位置,通常為空,表示讓系統來選擇共享記憶體的地址。
  • 第三個引數,shm_flg是一組標誌位,通常為0。

呼叫成功時返回一個指向共享記憶體第一個位元組的指標,如果呼叫失敗返回-1.

2,訪問共享記憶體

3,刪除共享記憶體

int shmctl(int shm_id, int command, struct shmid_ds *buf);
  • 第一個引數,shm_id是shmget()函式返回的共享記憶體識別符號。
  • 第二個引數,command是要採取的操作,它可以取下面的三個值 :
    • PC_STAT:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。
    • IPC_SET:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值
    • IPC_RMID:刪除共享記憶體段
  • 第三個引數,buf是一個結構指標,它指向共享記憶體模式和訪問許可權的結構。

1,建立共享記憶體,用到的函式shmget, shmat, shmdt

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

int main(){
  int shm;
  char* ptr;

  shm = shmget(IPC_PRIVATE, 129, IPC_CREAT | 0600);
  if(shm < 0){
    perror("shmget");
    return 1;
  }

  ptr = (char*)shmat(shm, NULL , 0);
  if(atoi(ptr) == -1){
    perror("shmat");
    return -1;
  }
  strcpy(ptr, "HELLO");

  shmdt(ptr);

  return 0;
}

github原始碼

用下面的命令,能夠檢視到上面的程式建立的共享記憶體。

ipcs -m

2,訪問共享記憶體

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

int main(int argc, char* argv[]){
  int shm;
  char* ptr;

  if(argc != 2){
    return 1;
  }

  shm = atoi(argv[1]);

  ptr = (char*)shmat(shm, NULL, 0);
  if(atoi(ptr) == -1){
    perror("shmat");
    return 1;
  }

  printf("string from shared memory : %s\n", ptr);

  shmdt(ptr);

  return 0;
}

github原始碼

執行方法:【ipcs -m】執行後,得到下面的數字。

./a.out 789884

3,刪除共享記憶體

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

int main(int argc, char* argv[]){
  int shm;
  shmid_ds sds;

  if(argc != 2){
    printf("argc is wrong");
    return 1;
  }

  shm = atoi(argv[1]);

  if(shmctl(shm, IPC_RMID, &sds) != 0){
    perror("shmctl");
    return 1;
  }

  return 0;
}

用命令列刪除共享記憶體:【ipcs -m】執行後,得到下面的數字。

ipcrm -m 321843

github原始碼

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854