|     本文關鍵字: 內存共享     1.實(shi)驗目的     通(tong)過(guo)編寫共(gong)享(xiang)(xiang)內(nei)存實驗(yan),進一步(bu)了解使用(yong)(yong)共(gong)享(xiang)(xiang)內(nei)存的(de)具體步(bu)驟,同(tong)(tong)時(shi)加深對共(gong)享(xiang)(xiang)內(nei)存的(de)理解。在(zai)本實驗(yan)中,采用(yong)(yong)信(xin)號(hao)量作為同(tong)(tong)步(bu)機制(zhi)(zhi)完善兩個(ge)進程(cheng)(“生(sheng)產者(zhe)(zhe)”和“消費者(zhe)(zhe)”)之間的(de)通(tong)信(xin),其功能類似(si)于4.6節中的(de)實例。在(zai)實例中使用(yong)(yong)信(xin)號(hao)量同(tong)(tong)步(bu)機制(zhi)(zhi)。     2.實驗內容     該實(shi)現要求利用共(gong)享內存(cun)實(shi)現文件(jian)的打開和讀寫操作。     3.實驗步驟     (1)畫出流程(cheng)圖(tu)。該實驗流程(cheng)圖(tu)如圖(tu)1所(suo)示。  圖1  實驗流程圖
     (2)編寫代碼。下面是共享內存緩沖區的數據結構(gou)的定義:     /* shm_com.h */#include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #define SHM_BUFF_SZ 2048
 struct shm_buff
 {
 int pid;
 char buffer[SHM_BUFF_SZ];
 };
     以下是“生產者”程序部分:     /* sem_com.h 和 sem_com.c 與4.4節示例中的同名程序相同 *//* producer.c */
 #include "shm_com.h"
 #include "sem_com.h"
 #include <signal.h>
 int ignore_signal(void)
 { /* 忽略一些信號,以免非法退出程序 */
 signal(SIGINT, SIG_IGN);
 signal(SIGSTOP, SIG_IGN);
 signal(SIGQUIT, SIG_IGN);
 return 0;
 }
 
 int main()
 {
 void *shared_memory = NULL;
 struct shm_buff *shm_buff_inst;
 char buffer[BUFSIZ];
 int shmid, semid;
 /* 定義信號量,用于實現訪問共享內存的進程間的互斥 */
 ignore_signal(); /* 防止程序非正常退出 */
 semid = semget(ftok(".", 'a'),  1, 0666|IPC_CREAT); /* 創建一個信號量 */
 init_sem(semid);/* 初始值為1 */
 
 /* 創建共享內存 */
 shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
 if (shmid == -1)
 {
 perror("shmget failed");
 del_sem(semid);
 exit(1);
 }
 
 /* 將共享內存地址映射到當前進程地址空間 */
 shared_memory = shmat(shmid, (void*)0, 0);
 if (shared_memory == (void*)-1)
 {
 perror("shmat");
 del_sem(semid);
 exit(1);
 }
 printf("Memory attached at %X\n", (int)shared_memory);
 /* 獲得共享內存的映射地址 */
 shm_buff_inst = (struct shared_use_st *)shared_memory;
 do
 {
 sem_p(semid);
 printf("Enter some text to the shared memory(enter 'quit' to exit):");
 /* 向共享內存寫入數據 */
 if (fgets(shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL)
 {
 perror("fgets");
 sem_v(semid);
 break;
 }
 shm_buff_inst->pid = getpid();
 sem_v(semid);
 } while(strncmp(shm_buff_inst->buffer, "quit", 4) != 0);
 
 /* 刪除信號量 */
 del_sem(semid);
 /* 刪除共享內存到當前進程地址空間中的映射 */
 if (shmdt(shared_memory) == 1)
 {
 perror("shmdt");
 exit(1);
 }
 exit(0);
 }
     以下是“消(xiao)費者”程序部分(fen):     /* customer.c */#include "shm_com.h"
 #include "sem_com.h"
 
 int main()
 {
 void *shared_memory = NULL;
 struct shm_buff *shm_buff_inst;
 int shmid, semid;
 /* 獲得信號量 */
 semid = semget(ftok(".", 'a'),  1, 0666);
 if (semid == -1)
 {
 perror("Producer is'nt exist");
 exit(1);
 }
 /* 獲得共享內存 */
 shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
 if (shmid == -1)
 {
 perror("shmget");
 exit(1);
 }
 /* 將共享內存地址映射到當前進程地址空間 */
 shared_memory = shmat(shmid, (void*)0, 0);
 if (shared_memory == (void*)-1)
 {
 perror("shmat");
 exit(1);
 }
 printf("Memory attached at %X\n", (int)shared_memory);
 /* 獲得共享內存的映射地址 */
 shm_buff_inst = (struct shm_buff *)shared_memory;
 do
 {
 sem_p(semid);	printf("Shared memory was written by process %d :%s",
 shm_buff_inst->pid, shm_buff_inst->buffer);
 if (strncmp(shm_buff_inst->buffer, "quit", 4) == 0)
 {
 break;
 }
 shm_buff_inst->pid = 0;
 memset(shm_buff_inst->buffer, 0, SHM_BUFF_SZ);
 sem_v(semid);
 } while(1);
 
 /* 刪除共享內存到當前進程地址空間中的映射 */
 if (shmdt(shared_memory) == -1)
 {
 perror("shmdt");
 exit(1);
 }
 /* 刪除共享內存 */
 if (shmctl(shmid, IPC_RMID, NULL) == -1)
 {
 perror("shmctl(IPC_RMID)");
 exit(1);
 }
 exit(0);
 }
     4.實驗結果     實(shi)驗運行結(jie)果如下(xia):     $./producerMemory attached at B7F90000
 Enter some text to the shared memory(enter 'quit' to exit):First message
 Enter some text to the shared memory(enter 'quit' to exit):Second message
 Enter some text to the shared memory(enter 'quit' to exit):quit
 $./customer
 Memory attached at B7FAF000
 Shared memory was written by process 3815 :First message
 Shared memory was written by process 3815 :Second message
    Shared memory was written by process 3815 :quit
     本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》    熱點鏈接: 
         1、linux 共享內存2、linux有名管道通信實驗
 3、linux 消息隊列
 4、linux下的信號量
 5、linux下的信號處理實例
 
 更多新聞>>  |