linux中shmget引數詳解

2021-10-04 15:08:48 字數 2747 閱讀 1808

#include

#include

int shmget (key_t key, size_t size, int shm***);

key標識共享記憶體的鍵值: 0/ ipc_private 。

當key的取值為ipc_private ,則函式shmget()將建立一塊新的 共享記憶體;       

如果key的取值為0 ,而引數shm***中設定了ipc_private 這個標誌,則同樣將建立一塊新的共享記憶體。

在ipc(程序間通訊)的通訊模式下,不管是使用訊息佇列還是共享記憶體,甚至是訊號量,每個ipc的物件(object)都有唯一的名字 ,稱為「鍵」(key)。通過「 鍵」,程序能夠識別所用的物件 。「鍵」與ipc物件的關係就如同檔名稱之於檔案,通過檔名,程序能夠讀寫檔案內的資料,甚至多個程序能夠共用乙個文 件。而在ipc的通訊模式下,通過「鍵」的使用也使得乙個ipc物件能為多個程序所共用。

linux系統中的所有表示system v中ipc物件的資料結構都包括乙個ipc_perm結構 ,其中包含有ipc物件的鍵值 ,該鍵用於查詢system v中ipc物件的引用識別符號。如果不使用「鍵」,程序將無法訪問ipc物件,因為ipc物件並不存在於程序本身使用的記憶體中。

通常,都希望自己的程式能和其他的程式預先約定乙個唯一的鍵值,但實際上並不是總可能的成行的,因為自己的程式無法為一塊共享記憶體選擇乙個鍵值 。因此,在 此把key設為ipc_private ,這樣,作業系統將忽略鍵,建立乙個新的共享記憶體,指定乙個鍵值 ,然後返回這塊共享記憶體ipc識別符號id。而將這個 新的共享記憶體的識別符號id告訴其他程序可以在建立共享記憶體後通過派生子程序,或寫入檔案或管道來實現。

size是要建立共享記憶體的長度。所有的記憶體分配操作都是以頁為單位的。所以如果一段程序只申請一塊只有乙個位元組的記憶體,記憶體也會分配整整一頁(在 i386機器中一頁的預設大小pace_size=4096位元組)這樣,新建立的共享記憶體的大小實際上是從size這個引數調整而來的頁面大小。即如果 size為1至4096,則實際申請到的共享記憶體大小為4k(一頁);4097到8192,則實際申請到的共享記憶體大小為8k(兩頁),依此類推。
shm***主要和一些標誌有關。其中有效的包括ipc_creat和ipc_excl,它們的功能與open()的o_creat和o_excl相當。

ipc_creat 如果共享記憶體不存在,則建立乙個共享記憶體,否則開啟操作。

ipc_excl 只有在共享記憶體不存在的時候,新的共享記憶體才建立,否則就產生錯誤。

如果單獨使用ipc_creat ,shmget()函式要麼返回乙個已經存在的共享記憶體的操作符 ,要麼返回乙個新建的共享記憶體的識別符號 。

如果將 ipc_creat和ipc_excl標誌一起使用,shmget()將返回乙個新建的共享記憶體的識別符號;如果該共享記憶體已存在,或者返回-1。 ipc_exel標誌本身並沒有太大的意義,但是和ipc_creat標誌一起使用可以用來保證所得的物件是新建的,而不是開啟已有的物件。

對於使用者的讀 取和寫入許可指定shm_r 和shm_w ,(shm_r>3)和(shm_w>3)是一組讀取和寫入許可,而(shm_r>6)和(shm_w>6)是全域性讀取和寫入許可。

成功返回共享記憶體的識別符號;不成功返回-1,errno儲存錯誤原因。

einval 引數size小於shmmin或大於shmmax。

eexist 預建立key所致的共享記憶體,但已經存在。

eidrm 引數key所致的共享記憶體已經刪除。

enospc 超過了系統允許建立的共享記憶體的最大值(shmall )。

enoent 引數key所指的共享記憶體不存在,引數shm***也未設ipc_creat位。

eacces 沒有許可權。

enomem 核心記憶體不足。

共享記憶體也有乙個給系統記憶體用來儲存相關資訊的結構,就是 shmid_ds。它在 linux/shm.h 中的定義是這樣的:

struct shmid_ds ;

其中,shm_perm 成員儲存了共享記憶體物件的訪問許可權及其它一些資訊。

shm_segsz 成員定義了共享的記憶體大小(以位元組為單位) 。

shm_atime 成員儲存了最近一次程序連線共享記憶體的時間。

shm_dtime 成員儲存了最近一次程序斷開與共享記憶體的連線的時間。

shm_ctime 成員儲存了最近一次 shmid_ds 結構內容改變的時間。

shm_cpid 成員儲存了建立共享記憶體的程序的 pid 。

shm_lpid 成員儲存了最近一次連線共享記憶體的程序的 pid。

shm_nattch 成員儲存了與共享記憶體連線的程序數目。

剩下的三個成員被核心保留使用,這裡就不介紹了。

shmid_ds資料結構表示每個新建的共享記憶體。當shmget()建立了一塊新的共享記憶體後,返回乙個可以用於引用該共享記憶體的shmid_ds資料結構的識別符號。

對於每個ipc物件,系統共用乙個struct ipc_perm的資料結構來存放許可權資訊,以確定乙個ipc操作是否可以訪問該ipc物件。

struct ipc_perm {

__kernel_key_t key;

__kernel_uid_t uid;

__kernel_gid_t gid;

__kernel_uid_t cuid;

__kernel_gid_t cgid;

__kernel_mode_t mode;

unsigned short seq;

Linux中的parse cmdline詳解

注 核心版本linux 2.6.30 parse cmdline的主要作用是用來解析命令列引數。其實現原理 乙個無窮迴圈,首先來查詢第乙個空格,如果找到,來空格之前的字串是否與early param相匹配,如果是,則通過實現的功能函式來找出其體引數。如果找到字串的末尾或cmdline的長度大於預設長...

Linux中Framebuffer驅動詳解1

之前看過很多書籍和網上資料,了解了linux中framebuffer的框架和一些結構體以及必備的硬體知識。但令本人深感 痛恨 的是,這些資料無不是點到為止 有些深入一些有些只介紹大概 貼 的時候總是省略了很多內容,難道就不能有一本書或一篇文章將整個framebuffer 全部講完嗎?在這裡我想 挑戰...

javascript中函式引數是evt詳解

一般情況下,在js中函式可能沒有引數,也有特殊情況,舉個例子 function togglecolor evt else if thissquare.classname else 先簡單介紹一下這個函式的作用 在乙個包含了若干卡片 的.html檔案中,單擊任何乙個小卡片改變卡片的背景顏色,再次單擊該...