文档章节

共享内存通信

青春无极限
 青春无极限
发布于 2017/03/27 16:20
字数 789
阅读 23
收藏 1


③共享内存通信

 

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

© 著作权归作者所有

青春无极限
粉丝 2
博文 127
码字总数 70524
作品 0
卢湾
程序员
私信 提问
加载中

评论(1)

python 基于mmap模块的jsonmmap实现本地多进程内存共享

python 基于mmap模块的jsonmmap实现本地多进程内存共享 1.概述 + 共享内存可以说是最有用的进程间通信方式.两个不用的进程共享内存的意思是:同一块物理内存被映射到两个进程的各自的进程地址...

ding465398889
2013/10/16
6K
8
20.进程与线程通信方式之间的差异

进程线程通信方式之间的差异 每个进程有自己的地址空间。两个进程中的地址即使值相同,实际指向的位置也不同。进程间通信一般通过操作系统的公共区进行。 同一进程中的线程因属同一地址空间,...

u014590757
2018/04/16
0
0
进程间通讯的方式

管道( pipe ): 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 有名管道 (named pipe) :有名管道也是半双工的...

旋转木马-千里马
2015/12/29
20
0
System V版本IPC进程间通信主题之共享内存

一.什么是共享内存 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。一旦这样的内存映射到共享它的进程的地址空间,这些进程...

lvyibin890
2017/06/09
0
0
linux/unix下多进程间的通信

进程:进程是计算机运行的基本单位,利用多进程可以实现系统的多任务;但是,在多进程的任务中,进程之间的通信是比较麻烦的,因为,进程之间使用的是不同的进程空间,所以,编写多进程的系统...

陈小花与胡汉三
2013/12/07
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

使用CSS自定义属性构建骨架屏

写在前面 几天前看到薄荷前端团队分享的《前端骨架屏方案小结》,突然回想起一年前看到的max bock写的《Building Skeleton Screens with CSS Custom Properties》,翻译整理写下出此文,分享...

前端老手
昨天
4
0
Docker常用命令小记

除了基本的<font color="blue">docker pull</font>、<font color="blue">docker image</font>、<font color="blue">docker ps</font>,还有一些命令及参数也很重要,在此记录下来避免遗忘。 ......

程序员欣宸
昨天
4
0
MAT使用-jvm内存溢出问题分析定位

1.MAT简介: MAT 全称 Eclipse Memory Analysis Tools 是一个分析 Java堆数据的专业工具,可以计算出内存中对象的实例数量、占用空间大小、引用关系等,看看是谁阻止了垃圾收集器的回收工作,...

xiaomin0322
昨天
5
0
内网和外网之间的通信(端口映射原理)

首先解释一下“内网”与“外网”的概念: 内网:即所说的局域网,比如学校的局域网,局域网内每台计算机的IP地址在本局域网内具有互异性,是不可重复的。但两个局域网内的内网IP可以有相同的...

Jack088
昨天
6
0
3.深入jvm内核-原理、诊断与优化-4. GC算法和种类

一、GC算法和种类 GC的概念 GC算法 引用计数法 标记清除 标记压缩 复制算法 可触及性 Stop-The-World GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者...

hexiaoming123
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部