③共享内存通讯 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.大概就是这样。指针