1. 程式人生 > >linux記憶體共享

linux記憶體共享

利用共享記憶體讀取系統log

首先定義一個儲存內容的結構體

 1 static struct shbuf_ds 
 2 {
 3     int size;                                // size of data written
 4     int head;                                // start of message list
 5     int tail;                                // end of message list
 6     char data[1];                            //
data/messages 7 } *flashsyslog_buf = NULL, *buf = NULL; // shared memory pointer 8 9 10 11 static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup 12 static struct sembuf SMrdn[2] = {{1, 0, 0}, {0, +1, SEM_UNDO}}; // set SMrdn 13 14 15 if (-1 == (flashsyslog_shmid = shmget(FLASHSYSLOG_KEY_ID, 0
, 0))) 16 { 17 printf("Syslog disabled or log buffer not allocated\n"); 18 buffer[0]='\0'; 19 goto output_end; 20 } 21 // Attach shared memory to our char* 22 if (NULL == (flashsyslog_buf = shmat(flashsyslog_shmid, NULL, SHM_RDONLY))) 23 { 24 vosLog_error("
Can't get access to circular buffer from syslogd\n"); 25 end = 1; 26 goto output_end; 27 } 28 printf("head:%d,tail:%d,size:%d",flashsyslog_buf->head,flashsyslog_buf->tail,flashsyslog_buf->size); 29 if (-1 == (flashsyslog_semid = semget(FLASHSYSLOG_KEY_ID, 0, 0))) 30 { 31 printf("Can't get access to semaphone(s) for circular buffer from syslogd\n"); 32 end = 1; 33 goto output_end; 34 } 35 36 semop(flashsyslog_semid,SMrdn,2); 37 38 39 40 output_end: 41 if (-1 != flashsyslog_shmid) 42 { 43 shmdt(flashsyslog_buf); 44 }

 

最後記得呼叫semop()函式將訊號down掉

1、shmget()函式

該函式用來建立共享記憶體,它的原型為:

int shmget(key_t key, size_t size, int shmflg);

第一個引數,與訊號量的semget函式一樣,程式需要提供一個引數key(非0整數),它有效地為共享記憶體段命名,shmget()函式成功時返回一個與key相關的共享記憶體識別符號(非負整數),用於後續的共享記憶體函式。呼叫失敗返回-1.

不相關的程序可以通過該函式的返回值訪問同一共享記憶體,它代表程式可能要使用的某個資源,程式對所有共享記憶體的訪問都是間接的,程式先通過呼叫shmget()函式並提供一個鍵,再由系統生成一個相應的共享記憶體識別符號(shmget()函式的返回值),只有shmget()函式才直接使用訊號量鍵,所有其他的訊號量函式使用由semget函式返回的訊號量識別符號。

第二個引數,size以位元組為單位指定需要共享的記憶體容量

第三個引數,shmflg是許可權標誌,它的作用與open函式的mode引數一樣,如果要想在key標識的共享記憶體不存在時,建立它的話,可以與IPC_CREAT做或操作。共享記憶體的許可權標誌與檔案的讀寫許可權一樣,舉例來說,0644,它表示允許一個程序建立的共享記憶體被記憶體建立者所擁有的程序向共享記憶體讀取和寫入資料,同時其他使用者建立的程序只能讀取共享記憶體。

2、shmat()函式    -- at:attach

第一次建立完共享記憶體時,它還不能被任何程序訪問,shmat()函式的作用就是用來啟動對該共享記憶體的訪問,並把共享記憶體連線到當前程序的地址空間。它的原型如下:

void *shmat(int shm_id, const void *shm_addr, int shmflg);

第一個引數,shm_id是由shmget()函式返回的共享記憶體標識。

第二個引數,shm_addr指定共享記憶體連線到當前程序中的地址位置,通常為空,表示讓系統來選擇共享記憶體的地址。

第三個引數,shm_flg是一組標誌位,通常為0。

呼叫成功時返回一個指向共享記憶體第一個位元組的指標,如果呼叫失敗返回-1.

3、shmdt()函式    -- dt:detach

該函式用於將共享記憶體從當前程序中分離。注意,將共享記憶體分離並不是刪除它,只是使該共享記憶體對當前程序不再可用。它的原型如下:

int shmdt(const void *shmaddr);

引數shmaddr是shmat()函式返回的地址指標,呼叫成功時返回0,失敗時返回-1.

4、shmctl()函式    -- ctl:control

與訊號量的semctl()函式一樣,用來控制共享記憶體,它的原型如下:

int shmctl(int shm_id, int command, struct shmid_ds *buf);

第一個引數,shm_id是shmget()函式返回的共享記憶體識別符號。

第二個引數,command是要採取的操作,它可以取下面的三個值 :

  • IPC_STAT:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。
  • IPC_SET:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值
  • IPC_RMID:刪除共享記憶體段

第三個引數,buf是一個結構指標,它指向共享記憶體模式和訪問許可權的結構。

shmid_ds結構 至少包括以下成員:

 1 struct shmid_ds
 2 {
 3 
 4     uid_t shm_perm.uid;
 5 
 6     uid_t shm_perm.gid;
 7 
 8     mode_t shm_perm.mode;
 9 
10 };