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;
}
用下面的命令,能夠查看到上面的程序創建的共享內存。
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;
}
執行方法:【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