久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Linux中如何共享內存

157次閱讀
沒有評論

共計 4738 個字符,預計需要花費 12 分鐘才能閱讀完成。

這篇文章給大家分享的是有關 Linux 中如何共享內存的內容。丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,一起跟隨丸趣 TV 小編過來看看吧。

1 共享內存的概念及使用過程

1) 共享內存的概念

共享內存是 IPC 機制中的一種。

共享內存:即允許兩個或多個進程共享一個給定的存儲區。

2) 共享內存的使用過程

① 進程 1 創建共享內存,接著映射共享內存。

② 進程 2 獲取共享內存,映射共享內存。

③ 交互完成,進程 1 分離共享內存,進程 2 分離共享內存。

④ 進程 1 刪除共享內存。

2 共享內存相關的結構及函數

0) 共享內存相關的結構

內核為每個共享存儲段維護著一個結構,該結構至少要為每個共享存儲段包含以下成員。

struct shmid_ds { struct ipc_perm shm_perm; //  操作權限  size_t shm_segsz; //  段的大小(以字節為單位) time_t shm_atime; //  上一個進程附加到該段的時間  time_t shm_dtime; //  上一個進程分離開該段的時間  time_t shm_ctime; //  上一個進程修改該段的時間  pid_t shm_cpid; //  創建該段進程的 PID pid_t shm_lpid; //  上個 shmat(2)/shmdt(2) 的 PID shmatt_t shm_nattch; //  當前附加到該段的進程的個數  ... };

系統為每一個 IPC 對象保存一個 ipc_perm 結構體,該結構說明了 IPC 對象的權限和所有者,每一個版本的內核各有不用的 ipc_perm 結構成員。

struct ipc_perm { key_t __key; //  為  shmget(2)  調用提供的鍵值  uid_t uid; //  共享內存所有者的有效用戶 UID gid_t gid; //  共享內存所有者所屬組的有效組 GID uid_t cuid; //  共享內存創建者的有效用戶 UID gid_t cgid; //  共享內存創建者所屬組的有效組 ID unsigned short mode; //  特權  + SHM_DEST  和 SHM_LOCKED  標志  unsigned short __seq; //  序列號  };

1)shmget 函數

shmget 函數用于創建或者獲取共享內存,并返回其描述符 id。

① 函數原型。

int shmget(key_t key,size_t sizie,int shmflg)

② 頭文件。

include  sys/ipc.h  include  sys/shm.h

③ 參數。

key: 共享內存的鍵值。

size: 共享內存的大小。

shmflg: 打開標志,如果使用了 IPC_CREAT,則會新創建一塊共享內存。

④ 返回值。

成功:返回創建或者獲取到的共享內存的描述符。

失敗:-1。

2)shmat 函數

shmat 函數用于映射共享內存,即將進程連接到它的地址空間。

① 函數原型。

void *shmat(int shmid,const void *shmaddr,int shmflg)

② 頭文件。

include  sys/types.h  include  sys/shm.h

③ 參數。

shmid: 要映射的共享內存的描述符。

shmaddr: 共享內存的地址。

shmflg: 打開標志,如果使用了 IPC_CREAT, 則會新創建一塊共享內存。

④ 返回值。

成功:返回創建或者獲取到的共享內存的描述符。

失敗:-1。

3)shmdt 函數

shmdt 函數用于分離共享內存,即操作完存儲段后,用此函數可以將進程與此存儲段脫離開,即斷掉與共享內存的聯系。

① 函數原型。

int shmdt(const void *shmaddr)

② 頭文件。

#include  sys/types.h  #include  sys/shm.h

③ 參數。

shmaddr: 要斷開的共享內存的映射地址。

④ 返回值。

成功:0。

失敗:-1。

4)shmctl 函數

shmctl 函數用于控制共享內存,通過參數可以對共享內存進行特定的操作。

① 函數原型。

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

② 頭文件。

#include  sys/ipc.h  #include  sys/shm.h

③ 參數。

shmid: 要控制的共享內存的 id。

cmd: 決定執行什么樣的控制操作,如 IPC_RMID(表示刪除)。

buf: 獲取 linux 中描述共享內存的 shmid_ds 結構。基本不使用。

cmd 可去的參數如下,需要參照上面的結構 shmid_ds 和 ipc_perm:

IPC_STAT:取此段的 shmid_ds 結構,并將它存儲在由 buf 指向的結構中。

IPC_SET:按 buf 指向的結構中的值設置與此共享存儲段相關的 shmid_ds 結構中的下列 3 個字段:shmperm.uid、shm  perm.gid 和 shmperm.mode。

此命令只能由下列兩種進程執行:一種是其有效用戶 ID 等于 shm_perm.cuid 或 shmperm.uid 的進程; 另一種是具有超級用戶特權的進程。

IPC_RMID:從系統中刪除該共享存儲段。

除非使用該段的最后一個進程終止或與該段分離,否則不會實際上刪除該存儲段。

不管此段是否仍在使用,該段標識符都會被立即刪除,所以不能再用 shmat 與該段連接。

此命令只能由下列兩種進程執行:一種是其有效用戶 ID 等于 shm_perm.cuid 或 shm_perm.uid 的進程; 另一種是具有超級用戶特權的進程。

下面兩個命令只能由超級用戶執行:

SHM_LOCK:在內存中對共享存儲段加鎖。

SHM_UNLOCK:解鎖共享存儲段。

④ 返回值。

成功:根據不同的操作返回不同的值。

失敗:-1。

3 實例代碼

下面用兩個進程,給大家演示下共享內存的使用過程。

實例代碼如下,說明都在代碼注釋中了。

WriteMemory.c。

#include  sys/types.h  #include  sys/shm.h #include  sys/ipc.h  #include  stdio.h  #include  unistd.h  #include  stdlib.h  #include  string.h  #define SIZE 1024 //  可輸入 1K 字符串  struct SharedMemoryST { int ReadWriteFlag; //  表明是誰放進去的  char CharData[SIZE]; //  字符數組保存用戶輸入數據  }; int main(int argc,char *argv[]) { int shmid; int ReadStatusFlag = 1; //  內存中數據是否被讀走,1 未被讀走  struct SharedMemoryST *shm; //  共享內存結構變量  char buffer[SIZE]; key_t key=ftok(/tmp ,12); //  創建共享內存的鍵值,如果提示創建失敗(一般是沒有 quit 引起的),可以修改讀寫進程的鍵值,都要改成同一數字  //1  創建共享內存  shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|IPC_EXCL|0777); if(shmid == -1) //  如果創建失敗  { printf( \nCreating share memory fail!\n\n  exit(1); } //2  映射共享內存  shm = shmat(shmid,NULL,0); //  內存 id,映射的位置,映射的標志(此無特殊要求) //3  查詢寫入的  while(ReadStatusFlag) //  循環檢查寫入共享內存的數據是否被讀走,讀走后退出循環  { while(shm- ReadWriteFlag == 1) { sleep(1); printf(\nWaiting read memory!\n  } //  獲取用戶輸入  printf(\nPlease input data or input  quit  to exit!\n\n  fgets(buffer,SIZE,stdin); //  參數:字符串的位置,長度,獲取的方式位置  //  將用戶輸入的字符串放入共享內存  strncpy(shm- CharData,buffer,SIZE);//  參數:目的數據,源數據,數據大小  shm- ReadWriteFlag = 1; if(strncmp(buffer, quit ,4) == 0) //  最后一個參數為比較字符的數量  { ReadStatusFlag = 0; //  寫入共享內存的數據已經被讀走  } } //4  脫離共享存  shmdt((const void *)shm); return 0; }

ReadMemory.c。

#include  sys/types.h  #include  sys/shm.h #include  sys/ipc.h  #include  stdio.h  #include  unistd.h  #include  stdlib.h  #define SIZE 1024 //  可輸入 1K 字符串  struct SharedMemoryST { int ReadWriteFlag; //  標明是讀進程還是寫進程放入了數據  char CharData[SIZE]; //  保存用戶輸入數據  }; int main(int argc,char *argv[]) { int shmid; int ReadStatusFlag = 1; //  內存中數據是否被讀走的標志位,1 表示未被讀走  struct SharedMemoryST *shm; //  共享內存結構  key_t key=ftok( /tmp ,12); //  創建共享內存的鍵值,如果提示創建失敗,修改一下數字即可, 讀寫進程都要改成同一數字  //1  創建 / 獲取共享內存  shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|0777);// 分配大小為結構大小,1234 是隨便給的鍵值  //2  映射共享內存  shm = (struct SharedMemoryST *)shmat(shmid,NULL,0); // 內存 id,映射的位置,映射的標志(此無特殊要求) shm- ReadWriteFlag = 0; //3  檢查是否收到信息,收到 quit 退出  while(ReadStatusFlag) { // 打印共享內存  if(shm- ReadWriteFlag == 1) //  等于說明有相應的數據  { printf( \nThe write context is: %s\n ,shm- CharData); shm- ReadWriteFlag = 0; if(strncmp(shm- CharData, quit ,3) == 0) { ReadStatusFlag = 0; //  結束查詢,退出  } } } //4  脫離共享內存  shmdt((const void *)shm); //5  刪除共享內存  shmctl(shmid,IPC_RMID,0); }

寫共享內存先創建共享內存, 寫入數據,讀共享內存讀取數據,通過標志查詢方式,退出輸入 quit。

運行結果如下:

感謝各位的閱讀!關于“Linux 中如何共享內存”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-25發表,共計4738字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 临朐县| 鄂温| 昌都县| 班戈县| 自贡市| 横山县| 象州县| 新巴尔虎右旗| 林口县| 仲巴县| 霸州市| 河源市| 苍山县| 武功县| 温宿县| 乡城县| 张家界市| 庄河市| 安塞县| 东山县| 扶余县| 安国市| 荔浦县| 普洱| 邛崃市| 中西区| 三原县| 中宁县| 弥勒县| 阿坝| 永靖县| 乌海市| 万宁市| 阿瓦提县| 石阡县| 乌恰县| 青神县| 赫章县| 福清市| 凤阳县| 吉安市|