一、共享內存的概念
共享內存(Shared Memory)就是允許多個進程訪問同一個內存空間,是在多個進程之間共享和傳遞數據最高效的方式。操作系統將不同進程之間共享內存安排為同一段物理內存,進程可以將共享內存連接到它們自己的地址空間中,如果某個進程修改了共享內存中的數據,其它的進程讀到的數據也將會改變。
共享內存並未提供鎖機制,也就是說,在某一個進程對共享內存的進行讀寫的時候,不會阻止其它的進程對它的讀寫。如果要對共享內存的讀/寫加鎖,可以使用信號燈。
二、相關函數
Linux中提供了一組函數用於操作共享內存,程序中需要包含以下頭文件:
#include <sys/ipc.h>
#include <sys/shm.h>
1、shmget函數
shmget函數用來獲取或創建共享內存,它的聲明為:
int shmget(key_t key, size_t size, int shmflg);
參數key是共享內存的鍵值,是一個整數,typedef unsigned int key_t,是共享內存在系統中的編號,不同共享內存的編號不能相同,這一點由程序員保證。key用十六進制表示比較好。
參數size是待創建的共享內存的大小,以字節為單位。
參數shmflg是共享內存的訪問權限,與文件的權限一樣,0666|IPC_CREAT表示全部用戶對它可讀寫,如果共享內存不存在,就創建一個共享內存。
2、shmat函數
把共享內存連接到當前進程的地址空間。它的聲明如下:
void *shmat(int shm_id, const void *shm_addr, int shmflg);
參數shm_id是由shmget函數返回的共享內存標識。
參數shm_addr指定共享內存連接到當前進程中的地址位置,通常為空,表示讓系統來選擇共享內存的地址。
參數shm_flg是一組標志位,通常為0。
調用成功時返回一個指向共享內存第一個字節的指針,如果調用失敗返回-1.
3、shmdt函數
該函數用於將共享內存從當前進程中分離,相當於shmat函數的反操作。它的聲明如下:
int shmdt(const void *shmaddr);
參數shmaddr是shmat函數返回的地址。
調用成功時返回0,失敗時返回-1.
4、shmctl函數
刪除共享內存,它的聲明如下:
int shmctl(int shm_id, int command, struct shmid_ds *buf);
參數shm_id是shmget函數返回的共享內存標識符。
參數command填IPC_RMID。
參數buf填0。
解釋一下,shmctl是控制共享內存的函數,其功能不只是刪除共享內容,但其它的功能沒什么用,所以不介紹了。
注意,用root創建的共享內存,不管創建的權限是什么,普通用戶無法刪除。
三、示例程序
示例(book258.cpp)
/*
* 程序名:book258.cpp,此程序用於演示共享內存的用法
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include "_public.h"
int main()
{
int shmid; // 共享內存標識符
// 創建共享內存,鍵值為0x5005,共1024字節。
if ( (shmid = shmget((key_t)0x5005, 1024, 0640|IPC_CREAT)) == -1)
{ printf("shmat(0x5005) failed\n"); return -1; }
char *ptext=0; // 用於指向共享內存的指針
// 將共享內存連接到當前進程的地址空間,由ptext指針指向它
ptext = (char *)shmat(shmid, 0, 0);
// 操作本程序的ptext指針,就是操作共享內存
printf("寫入前:%s\n",ptext);
sprintf(ptext,"本程序的進程號是:%d",getpid());
printf("寫入后:%s\n",ptext);
// 把共享內存從當前進程中分離
shmdt(ptext);
// 刪除共享內存
// if (shmctl(shmid, IPC_RMID, 0) == -1)
// { printf("shmctl(0x5005) failed\n"); return -1; }
}
運行效果
注意,程序第一次運行的時候,共享內存未創建,所以第一次運行程序的時候,共享內存中的內容為空。之后程序每次運行都能獲取到上一次程序運行寫入的內容。
四、其它的操作命令
用ipcs -m可以查看系統的共享內存,內容有鍵值(key),共享內存編號(shmid),創建者(owner),權限(perms),大小(bytes)。
用ipcrm -m 共享內存編號,可以手工刪除共享內存,如下:
五、版權聲明
============
C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!