Linux共享內存


一、共享內存的概念

共享內存(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)
作者:碼農有道

如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!


免責聲明!

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



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