對于長期運行的系統(tǒng),產(chǎn)生的日志是大量的,即使每2秒一條,一天也有4W多條。假如我們只需要在想觀察的時候動態(tài)地看到當前記錄或計數(shù),那么可以將日志的信息寫到一個共享內(nèi)存區(qū),然后寫一個LogReader,去訪問這個共享內(nèi)存區(qū)即可。
?
要使用共享內(nèi)存,應該有如下步驟:
1.開辟一塊共享內(nèi)存 shmget()
2.允許本進程使用共某塊共享內(nèi)存 shmat()
3.寫入/讀出
需要刪除這塊內(nèi)存的時候,步驟為
4.禁止本進程使用這塊共享內(nèi)存 shmdt()
5.刪除這塊共享內(nèi)存 shmctl()或者命令行下ipcrm
?
過程會用到以下的這些函數(shù):
?int shmget( key_t shmkey , int shmsiz , int flag );
?創(chuàng)建一個新的共享內(nèi)存區(qū)或打開一存在的共享內(nèi)存區(qū)
?
void *shmat( int shmid , char *shmaddr , int shmflag );
返回共享內(nèi)存區(qū)在調(diào)用進程內(nèi)的起始地址。 shmaddr最好設置為NULL,這樣系統(tǒng)會替我們選擇地址,可移植性更強;否則會根據(jù)shmflag時候指定了SHM_RND,將共享內(nèi)存區(qū)附接到shmaddr參數(shù)指定的地址。
?
今天調(diào)試的時候發(fā)現(xiàn)了以下的這些問題:兩個需要通信的進程使用一個同樣的字符串調(diào)用ftok生成key,并對該key調(diào)用shmget,其中有一個不能訪問到共享內(nèi)存區(qū)。查閱了UNP2才明白了。
ftok將一個已存在的路徑名和一個整數(shù)標識符轉(zhuǎn)換成一個key_t值。
???? key_t ftok(const char *pathname, int proj_id)
ftok會組合三個值來產(chǎn)生key:
1、pathname所在的文件系統(tǒng)的信息。
2、該文件在本文件系統(tǒng)內(nèi)的索引節(jié)點號。
3、id的低序8位。
?
key_t的生成是以一個已存在的文件作為輸入,并不是簡單的字符串散列函數(shù),必須真正存在某個文件,才能將其位置傳入ftok。