③共享內存通訊 share.h #define TEXT_SZ 2048 //申請共享內存大小 struct shared_use_st { int written_by_you; //written_by_you爲1時表示有數據寫入,爲0時表示數據已經被消費者提走 char some_text[TEXT_SZ]; }; producer.c #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include "share.h" int main() { int running = 1; //程序運行標誌位 void *shared_memory = (void *)0; struct shared_use_st *shared_stuff; char buffer[BUFSIZ]; int shmid; //共享內存標識符 /*建立共享內存*/ shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); if (shmid == -1) { fprintf(stderr, "shmget failed/n"); exit(EXIT_FAILURE); } /*將共享內存鏈接到一個進程的地址空間中*/ shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個字節的指針 if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed/n"); exit(EXIT_FAILURE); } printf("Memory attached at %X/n", (int)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; /*生產者寫入數據*/ while(running) { while(shared_stuff->written_by_you == 1) { sleep(1); printf("waiting for client.../n"); } printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); strncpy(shared_stuff->some_text, buffer, TEXT_SZ); shared_stuff->written_by_you = 1; if (strncmp(buffer, "end", 3) == 0) { running = 0; } } /*該函數用來將共享內存從當前進程中分離,僅使得當前進程再也不能使用該共享內存*/ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed/n"); exit(EXIT_FAILURE); } printf("producer exit./n"); exit(EXIT_SUCCESS); } customer.c #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include "share.h" int main() { int running = 1;//程序運行標誌位 void *shared_memory = (void *)0; struct shared_use_st *shared_stuff; int shmid; //共享內存標識符 srand((unsigned int)getpid()); /*建立共享內存*/ shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); if (shmid == -1) { fprintf(stderr, "shmget failed/n"); exit(EXIT_FAILURE); } /*將共享內存鏈接到一個進程的地址空間中*/ shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個字節的指針 if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed/n"); exit(EXIT_FAILURE); } printf("Memory attached at %X/n", (int)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; shared_stuff->written_by_you = 0; /*消費者讀取數據*/ while(running) { if (shared_stuff->written_by_you) { printf("You wrote: %s", shared_stuff->some_text); sleep( rand() % 4 ); shared_stuff->written_by_you = 0; if (strncmp(shared_stuff->some_text, "end", 3) == 0) { running = 0; } } } /*該函數用來將共享內存從當前進程中分離,僅使得當前進程再也不能使用該共享內存*/ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed/n"); exit(EXIT_FAILURE); } /*將共享內存刪除,全部進程均不能再訪問該共享內存*/ if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed/n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
關於共享內存的原理,咱們須要細細講下,否則不少同窗搞不清楚是怎麼一回事。函數
首先說明一下:共享內存是IPC間通訊最快的一種方式。並且不依賴於時間。如消息隊列,若是你發送了就要接受。共享內存一個進程只須要把數據放到共享內存歷,而後另外一個進程能夠隨時讀取,很方便。對於共享內存的這個內存空間。咱們須要很詳細的講下:其實並非一塊真正的物理內存空間,而是一塊虛擬內存,而且是連續的虛擬地址空間,然而映射到物理地址上,則是無數塊不連續的閒置的大塊物理內存。這樣能夠省資源。好比共享內存定義的地0000不必定是物理內存的0000,有多是1211.大概就是這樣。指針