這篇文章給大家分享的是有關Linux中如何共享內存的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
成都創(chuàng)新互聯(lián)公司是一家集成都網站建設、網站設計、網站頁面設計、網站優(yōu)化SEO優(yōu)化為一體的專業(yè)網站建設公司,已為成都等多地近百家企業(yè)提供網站建設服務。追求良好的瀏覽體驗,以探求精品塑造與理念升華,設計最適合用戶的網站頁面。 合作只是第一步,服務才是根本,我們始終堅持講誠信,負責任的原則,為您進行細心、貼心、認真的服務,與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
1 共享內存的概念及使用過程
1)共享內存的概念
共享內存是IPC機制中的一種。
共享內存:即允許兩個或多個進程共享一個給定的存儲區(qū)。
2)共享內存的使用過程
① 進程1創(chuàng)建共享內存,接著映射共享內存。
② 進程2獲取共享內存,映射共享內存。
③ 交互完成,進程1分離共享內存,進程2分離共享內存。
④ 進程1刪除共享內存。
2 共享內存相關的結構及函數(shù)
0)共享內存相關的結構
內核為每個共享存儲段維護著一個結構,該結構至少要為每個共享存儲段包含以下成員。
struct shmid_ds { struct ipc_perm shm_perm; // 操作權限 size_t shm_segsz; // 段的大?。ㄒ宰止?jié)為單位) time_t shm_atime; // 上一個進程附加到該段的時間 time_t shm_dtime; // 上一個進程分離開該段的時間 time_t shm_ctime; // 上一個進程修改該段的時間 pid_t shm_cpid; // 創(chuàng)建該段進程的PID pid_t shm_lpid; // 上個shmat(2)/shmdt(2)的PID shmatt_t shm_nattch; // 當前附加到該段的進程的個數(shù) ... };
系統(tǒng)為每一個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; // 共享內存創(chuàng)建者的有效用戶UID gid_t cgid; // 共享內存創(chuàng)建者所屬組的有效組ID unsigned short mode; // 特權 + SHM_DEST 和SHM_LOCKED 標志 unsigned short __seq; // 序列號 };
1)shmget函數(shù)
shmget函數(shù)用于創(chuàng)建或者獲取共享內存,并返回其描述符id。
① 函數(shù)原型。
int shmget(key_t key,size_t sizie,int shmflg)
② 頭文件。
include <sys/ipc.h> include <sys/shm.h>
③ 參數(shù)。
key:共享內存的鍵值。
size:共享內存的大小。
shmflg:打開標志,如果使用了IPC_CREAT,則會新創(chuàng)建一塊共享內存。
④ 返回值。
成功:返回創(chuàng)建或者獲取到的共享內存的描述符。
失?。?1。
2)shmat函數(shù)
shmat函數(shù)用于映射共享內存,即將進程連接到它的地址空間。
① 函數(shù)原型。
void *shmat(int shmid,const void *shmaddr,int shmflg)
② 頭文件。
include <sys/types.h> include <sys/shm.h>
③ 參數(shù)。
shmid:要映射的共享內存的描述符。
shmaddr:共享內存的地址。
shmflg:打開標志,如果使用了IPC_CREAT,則會新創(chuàng)建一塊共享內存。
④ 返回值。
成功:返回創(chuàng)建或者獲取到的共享內存的描述符。
失?。?1。
3)shmdt函數(shù)
shmdt函數(shù)用于分離共享內存,即操作完存儲段后,用此函數(shù)可以將進程與此存儲段脫離開,即斷掉與共享內存的聯(lián)系。
① 函數(shù)原型。
int shmdt(const void *shmaddr)
② 頭文件。
#include <sys/types.h> #include <sys/shm.h>
③ 參數(shù)。
shmaddr:要斷開的共享內存的映射地址。
④ 返回值。
成功:0。
失?。?1。
4)shmctl函數(shù)
shmctl函數(shù)用于控制共享內存,通過參數(shù)可以對共享內存進行特定的操作。
① 函數(shù)原型。
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
② 頭文件。
#include <sys/ipc.h> #include <sys/shm.h>
③ 參數(shù)。
shmid:要控制的共享內存的id。
cmd:決定執(zhí)行什么樣的控制操作,如IPC_RMID(表示刪除)。
buf:獲取linux中描述共享內存的shmid_ds結構?;静皇褂谩?/p>
cmd可去的參數(shù)如下,需要參照上面的結構shmid_ds和ipc_perm :
IPC_STAT:取此段的shmid_ds結構,并將它存儲在由buf指向的結構中。
IPC_SET:按buf指向的結構中的值設置與此共享存儲段相關的shmid_ds結構中的下列3個字段:shmperm.uid、shm perm.gid和shmperm.mode。
此命令只能由下列兩種進程執(zhí)行:一種是其有效用戶ID等于shm_perm.cuid或shmperm.uid的進程;另一種是具有超級用戶特權的進程。
IPC_RMID:從系統(tǒng)中刪除該共享存儲段。
除非使用該段的最后一個進程終止或與該段分離,否則不會實際上刪除該存儲段。
不管此段是否仍在使用,該段標識符都會被立即刪除,所以不能再用shmat與該段連接。
此命令只能由下列兩種進程執(zhí)行:一種是其有效用戶ID等于shm_perm.cuid或shm_perm.uid的進程;另一種是具有超級用戶特權的進程。
下面兩個命令只能由超級用戶執(zhí)行:
SHM_LOCK:在內存中對共享存儲段加鎖。
SHM_UNLOCK:解鎖共享存儲段。
④ 返回值。
成功:根據(jù)不同的操作返回不同的值。
失敗:-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]; // 字符數(shù)組保存用戶輸入數(shù)據(jù) }; int main(int argc,char *argv[]) { int shmid; int ReadStatusFlag = 1; // 內存中數(shù)據(jù)是否被讀走,1未被讀走 struct SharedMemoryST *shm; // 共享內存結構變量 char buffer[SIZE]; key_t key=ftok("/tmp",12); // 創(chuàng)建共享內存的鍵值,如果提示創(chuàng)建失?。ㄒ话闶菦]有quit引起的),可以修改讀寫進程的鍵值,都要改成同一數(shù)字 //1 創(chuàng)建共享內存 shmid = shmget(key,sizeof(struct SharedMemoryST),IPC_CREAT|IPC_EXCL|0777); if(shmid == -1) // 如果創(chuàng)建失敗 { printf("\nCreating share memory fail!\n\n"); exit(1); } //2 映射共享內存 shm = shmat(shmid,NULL,0); // 內存id,映射的位置,映射的標志(此無特殊要求) //3 查詢寫入的 while(ReadStatusFlag) // 循環(huán)檢查寫入共享內存的數(shù)據(jù)是否被讀走,讀走后退出循環(huán) { 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); // 參數(shù):字符串的位置,長度,獲取的方式位置 // 將用戶輸入的字符串放入共享內存 strncpy(shm->CharData,buffer,SIZE);// 參數(shù):目的數(shù)據(jù),源數(shù)據(jù),數(shù)據(jù)大小 shm->ReadWriteFlag = 1; if(strncmp(buffer,"quit",4) == 0) // 最后一個參數(shù)為比較字符的數(shù)量 { ReadStatusFlag = 0; // 寫入共享內存的數(shù)據(jù)已經被讀走 } } //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; // 標明是讀進程還是寫進程放入了數(shù)據(jù) char CharData[SIZE]; // 保存用戶輸入數(shù)據(jù) }; int main(int argc,char *argv[]) { int shmid; int ReadStatusFlag = 1; // 內存中數(shù)據(jù)是否被讀走的標志位,1表示未被讀走 struct SharedMemoryST *shm; // 共享內存結構 key_t key=ftok("/tmp",12); // 創(chuàng)建共享內存的鍵值,如果提示創(chuàng)建失敗,修改一下數(shù)字即可,讀寫進程都要改成同一數(shù)字 //1 創(chuàng)建/獲取共享內存 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) // 等于說明有相應的數(shù)據(jù) { 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); }
寫共享內存先創(chuàng)建共享內存,寫入數(shù)據(jù),讀共享內存讀取數(shù)據(jù),通過標志查詢方式,退出輸入quit。
運行結果如下:
感謝各位的閱讀!關于“Linux中如何共享內存”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
本文題目:Linux中如何共享內存
URL網址:http://www.rwnh.cn/article40/jgjjeo.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供手機網站建設、、關鍵詞優(yōu)化、定制開發(fā)、營銷型網站建設、外貿網站建設
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)