共享內存:
特點:
1、共享內存是一種最為高效的進程間通信方式,進程可以直接讀寫內存,而不需要任何數據的拷貝
2、為了在多個進程間交換信息,內核專門留出了一塊內存區,可以由需要訪問的進程將其映射到自己的私有地址空間
3、進程就可以直接讀寫這一內存區而不需要進行數據的拷貝,從而大大提高的效率。
4、由於多個進程共享一段內存,因此也需要依靠某種同步機制,如互斥鎖和信號量等

實現步驟:

主要函數:
1、 ftok(任意路徑,任意0-255之間的數);//利用ftok函數獲得一個key值

2、shmget(key值,空間大小,權限:例0666 | IPC_CREAT);//創建並打開共享內存創建共享內存:

3、char *p = (char *)shmat(shmID,NULL,0);//映射到用戶空間。

4、shmdt (p);//撤銷共享內存
5、shmctl(shmID,IPC_RMID,NULL);//刪除共享內存

案例:
qy.c:
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <semaphore.h> #include <fcntl.h> int main(void) { //有名信號量的創建 sem_t* sem_1 = sem_open("sem1", O_CREAT | O_RDONLY, 0666, 1); if(SEM_FAILED == sem_1) { perror("sem_open error"); return -1; } sem_t* sem_2 = sem_open("sem2", O_CREAT | O_RDONLY, 0666, 0); if(SEM_FAILED == sem_2) { perror("sem_open error"); return -1; } //獲得一個Key值 key_t key = ftok("./",10); //創建共享內存,返回一個內存ID int shmID = shmget(key, 200, 0666 | IPC_CREAT); if(-1 == shmID) { perror("shmget error"); return -1; } //映射到用戶空間返回空間地址 char *p = (char *)shmat(shmID, NULL, 0); if((void *)-1 == (void *)p) { perror("shmat error"); return -1; } //信號量的用法與無名相同 sem_wait(sem_2); printf("%s\n",p); sem_post(sem_1); //刪除信號量 sem_unlink(sem_1); sem_unlink(sem_2); //撤銷映射 shmdt(p); //刪除共享內存 shmctl(shmID, IPC_RMID, NULL); return 0; }
wf.c
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <semaphore.h> #include <fcntl.h> int main(void) { //有名信號量的創建 sem_t* sem_1 = sem_open("sem1", O_CREAT | O_RDONLY, 0666, 1); if(SEM_FAILED == sem_1) { perror("sem_open error"); return -1; } sem_t* sem_2 = sem_open("sem2", O_CREAT | O_RDONLY, 0666, 0); if(SEM_FAILED == sem_2) { perror("sem_open error"); return -1; } //獲得一個Key值 key_t key = ftok("./",10); //創建共享內存,返回一個內存ID int shmID = shmget(key, 200, 0666 | IPC_CREAT); if(-1 == shmID) { perror("shmget error"); return -1; } //映射到用戶空間返回空間地址 char *p = (char *)shmat(shmID, NULL, 0); if((void *)-1 == (void *)p) { perror("shmat error"); return -1; } //信號量的用法與無名相同 sem_wait(sem_1); printf("請輸入:"); gets(p); sem_post(sem_2); //關閉信號量文件 sem_close(sem_1); sem_close(sem_2); //撤銷映射 shmdt(p); //刪除共享內存 shmctl(shmID, IPC_RMID, NULL); return 0; }
makefile
APP: gcc qy.c -o qy -lpthread gcc wf.c -o wf -lpthread
注意:這里清空共享內存空間可以用memset();
在終端輸入ipcs -m 查看shmid
然后輸入ipcrm -m ID號 及刪除共享內存
