更多技術(shù)文章地址:http://www.hqyj.com/news/emb211.htm?lcg-ee 1.實(shí)驗目的 通過(guò)編寫(xiě)共享內存實(shí)驗,進(jìn)一步了解使用共享內存的具體步驟,同時(shí)加深對共享內存的理解。在本實(shí)驗中,采用信號量作為同步機制完善兩個(gè)進(jìn)程(“生產(chǎn)者”和“消費者”)之間的通信,其功能類(lèi)似于4.6節中的實(shí)例。在實(shí)例中使用信號量同步機制。 2.實(shí)驗內容 該實(shí)現要求利用共享內存實(shí)現文件的打開(kāi)和讀寫(xiě)操作。 3.實(shí)驗步驟 (1)畫(huà)出流程圖。該實(shí)驗流程圖如圖1所示。 ![]() 圖1 實(shí)驗流程圖 (2)編寫(xiě)代碼。下面是共享內存緩沖區的數據結構的定義: /* shm_com.h */ #include #include #include #include #include #include #include #define SHM_BUFF_SZ 2048 struct shm_buff { int pid; char buffer[SHM_BUFF_SZ]; }; 以下是“生產(chǎn)者”程序部分: /* sem_com.h 和 sem_com.c 與4.4節示例中的同名程序相同 */ /* producer.c */ #include "shm_com.h" #include "sem_com.h" #include 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; /* 定義信號量,用于實(shí)現訪(fǎng)問(wèn)共享內存的進(jìn)程間的互斥 */ ignore_signal(); /* 防止程序非正常退出 */ semid = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); /* 創(chuàng )建一個(gè)信號量 */ init_sem(semid);/* 初始值為1 */ /* 創(chuàng )建共享內存 */ shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT); if (shmid == -1) { perror("shmget failed"); del_sem(semid); exit(1); } /* 將共享內存地址映射到當前進(jìn)程地址空間 */ 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):"); /* 向共享內存寫(xiě)入數據 */ 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); /* 刪除共享內存到當前進(jìn)程地址空間中的映射 */ if (shmdt(shared_memory) == 1) { perror("shmdt"); exit(1); } exit(0); } 以下是“消費者”程序部分: /* 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); } /* 將共享內存地址映射到當前進(jìn)程地址空間 */ 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); /* 刪除共享內存到當前進(jìn)程地址空間中的映射 */ 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.實(shí)驗結果 實(shí)驗運行結果如下: $./producer Memory 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 |