使用共享記憶體實現一個程序寫檔案,兩個程序讀檔案
主要功能:讀取任意的檔案,大小不限(不超過共享記憶體設定的大小,一般為8k,但可手動重新設定,這已經很大了。),執行後兩個或多個讀程序可同時讀取該檔案並在終端列印。
要實現該功能,首先你得了解共享記憶體的搭建,有四個函式,分別為shmget,shmat,shmdt,shmctl,他們的作用如下:
1、shmget函式 該函式用來建立共享記憶體,它的原型為: [cpp] view plain copy print?- int shmget(key_t key, size_t size, int shmflg);
- void *shmat(int shm_id, constvoid *shm_addr, int shmflg);
- int shmdt(constvoid *shmaddr);
-
int shmctl(int shm_id, int command,
IPC_RMID:刪除共享記憶體段
第三個引數,buf是一個結構指標,它指向共享記憶體模式和訪問許可權的結構。 shmid_ds結構至少包括以下成員: [cpp] view plain copy print?
- struct shmid_ds
- {
- uid_t shm_perm.uid;
- uid_t shm_perm.gid;
- mode_t shm_perm.mode;
- };
具體思路:先寫後讀,寫程序先開啟檔案,然後往shmemory共享記憶體內寫入檔案,讀程序直接從共享記憶體中讀檔案,並打印出來。
三個檔案:shmwrite.c (寫程序) shmread.c(讀程序,可以有多個) sharemry.h(標頭檔案)
先看標頭檔案sharemry.h:
定義了flag是否可讀的標誌,size寫入檔案的大小,free_status是否最後一個讀程序,text是一個可變陣列,根據開啟的檔案大小開闢記憶體。無論是端還是寫端,都必須先掛載到同一共享記憶體上。
可變陣列:
text[0]結構
經常遇到的結構形狀如下:
struct buffer
{
int text_len; //長度
char text[0]; //起始地址
};
在這個結構中,text是一個數組名;但該陣列沒有元素;該陣列的真實地址緊隨結構體buffer之後,而這個地址就是結構體後面資料的地址(如果給這個結構體分配的內容大於這個結構體實際大小,後面多餘的部分就是這個text的內容);這種宣告方法可以巧妙的實現C語言裡的陣列擴充套件。
下圖是shmwrite.c寫程序原始碼:
掛載到共享記憶體之後,開始讀檔案並寫入共享記憶體
寫入完成,將程式和共享記憶體解除安裝,也即脫離。
最後是shmread.c:
接上圖
這裡就會用到flag,有兩個或多個程序同時讀同一個共享記憶體時,每個讀程序都會去掛載這塊建立好的共享記憶體,但是有個隱藏的bug,共享記憶體是公用的一塊,如果每個讀程序都去shmctl共享記憶體的話,會出現錯誤,類似於記憶體洩露。所以標誌flag保證最後一個讀程序退出時才刪除共享記憶體。