共享內存通訊

③共享內存通訊

 

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.大概就是這樣。指針

相關文章
相關標籤/搜索