共享内存通讯

③共享内存通讯

 

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.大概就是这样。指针

相关文章
相关标签/搜索