Linux 进程间通讯(IPC)方式有以下几种:

1-》管道(pipe)和有名管道(fifo).

2-》消息队列

3-》共享内存

4-》信号量

5-》信号(signal)

6-》套接字(sicket)

在这里我们看一下第3种====共享内存(share memory )。其它通信方式见其它文章。

顾名思义:共享内存就是两个或多个进程共享一块内存区域。

这种通信方式允许两个不相关的进程能够访问处理同一块内存区域。从而达到进程间数据的交换和处理等。在这些进行通信方式中,共享内存是一种非常高效的通信方式,一种最快的通信方式。为什么快呢?只要我们向一个进程汇总写入的数据,则共享这个内存区域的所有进程都可见,从而达到提醒的目的。可以归为一句话:一处改变,随处可见。

原理:

共享内存是被多个进程共享的一块物理内存,而这些内存就是把共享内存区域映射到自己的虚拟内存中。从而对共享内存进行操作。

================================================

共享内存比pipe的优势:
1.用在任何进程,不比考虑进程关系,
2.读走后还存在数据
3.可以随机读取所需要的数据

=============================================

接下来我们看一下关于共享内存的操作函数:

主要有:shmget();shmat();shmdt();shmctl();

在使用这些函数需引进头文件#include<sys/ipc.h>和#include<sys/shm.h>

我们都知道在计算机的世界里什么都必须先声明后使用,对此也不例外。

要实现共享内存通信,必须现有共享内存的区域。

下面我们看一下shmget函数。

函数原型:int shmget(key_t    _key,     size_t   _size,   int  _shmflg);

功能:创建共享内存

返回值:返回共享内存的标识码。失败返回-1。

参数说明:

_key  :标识共享内存的键值。有IPC _PRIVATE选项表示该内存块为该进程私有,一般不用。

_size :表示要建立共享内存的长度。我们一般用getpagesize();函数来设定,此函数的返回值为4096个字节。

_shmflg: 标志,是权限或创建方式。

创建方式有:IPC_CREAT如果内存不存在则创建一个共享内存,否则打开。

IPC_EXCL 只有共享内存不存在的时候,新的共享内存才会被创建,否则会产生错误。

下面我们简单地看一个小例子:

/*

demo shmfet

*/

#include<stdio.h>

#include<fcntl.h>

#include<stdlib.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include <unistd.h>

int main(int argc ,char *argv[])

{

int shmid;

shmid = shmget(IPC_PRIVATE ,getpagesize(),IPC_CREAT | IPC_EXCL | 0666);

//getpagesize() return 4096.

if(shmid == -1)

{

perror("shmget error:");

exit(EXIT_FAILURE);

}

printf("shmid=%d\n",shmid);//在此我们打印创建的内存表识ID

return 0;

}

运行结果为:我们可以用ipcs  -m(查看系统共享内存块信息 的命令)来查看是否被创建成功。

当然也可以删除删除共享内存命令为: ipcrm   shm   shmid列的列号(共享内存的标识ID)。

eg:   ipcrm shm 4816896

通常情况下,该_key值通过ftok函数得到,来生成唯一的KEY值ID

int   key_t key;

key=ftok("/etc/passwd",1234);

int   shmid=shmget(key,getpagesize(),IPC_CREAT | IPC_EXCL | 0666);

注: #include <sys/types.h>

#include <sys/ipc.h>

如下:

key_t ftok( char * fname, int id )

fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如:

key_t key;

key = ftok(".", 1); 这样就是将fname设为当前目录。

id是子序号。

在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。

如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。

查询文件索引节点号的方法是: ls -i

当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。

如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值

int    shmid=shmget(6666 ,getpagesize(),IPC_CREAT | IPC_EXCL | 0666);

下面看个例子:

/*

demo shmfet   2

*/

#include<stdio.h>

#include<fcntl.h>

#include<stdlib.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include <unistd.h>

int main(int argc ,char *argv[])

{

int shmid;

int  key_t    key;

key=ftok(“.”,1234);

Shmid=shmget(key ,getpagesize(),IPC_CREAT |  IPC_EXCL | 0666);

//getpagesize() return 4096.

if(shmid == -1)

{

perror("shmget error:");

exit(EXIT_FAILURE);

}

printf("shmid=%d\n",shmid);//在此我们打印创建的内存表识ID

return 0;

}

运行结果:

会提示file    exits  因为我们已经指定一个固定的key_t值。

====================================================================

下面我们看第二个函数

#include<sys/shm.h>

#include<sys/ipc.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

功能:允许进程访问共享内存。

返回值:成功返回共享内存的起始地址,失败返回-1.

参数:

_Shmid   共享内存的ID ,也就是shmget();函数的返回值。

_Shmaddr 共享内存的起始地址。一般指定为0.

_ shmflg  是本进程对共享内存的操作模式。一般指定为0,即可读可写。

如果指定为SHM_RDONLY 的话就是只读模式。

提示:后卖弄我们会看个例子。

下面我们看第3个函数

使用完了内存我们要进行释放操作。

#include<sys/shm.h>

#include<sys/ipc.h>

Int shmdt(  _const  void *_shmaddr);

功能:释放共享内存,虽然释放不用了,但是共享内存仍然存在。

参数:共享内存的起始地址;就是shmat();函数的返回值。

返回值:成功返回0,失败返回-1.

下面我们看第4个函数;

#include<sys/shm.h>

#include<sys/ipc.h>

Int   shmctl(int _shmid,int _cmd ,struct shmid _ds *buf);

功能:共享内存的控制函数

返回值:成功返回0,失败返回-1.

参数:_shmid     共享内存的ID。

_cmd    允许的存在,最常用的有IPC_RMID 删除共享内存的内存段。

buf   不错内存模式状态和访问权限的数据结构,通常为0.

=====================================================================================================

Ok,看例子,让程序验证真理:

我们来实现BMI 指数:体重指数来衡量肥胖我们以

20~25为正常

<20 偏瘦 >25偏胖计算,可能不是这个值。但主要是通信(*^__^*)嘻嘻……

===================================================================================================

源文件1:

#include<stdio.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include<stdlib.h>

int main(int argc ,char *argv[])

{

int shmid;

float *addr;

float h,w,flag=1.0f;//flag 作为判断循环的标志

shmid= shmget(ftok("./file",1000),getpagesize(),IPC_CREAT | IPC_EXCL | 0666);

if(shmid==-1)

{

perror("shmget error:");

exit(EXIT_FAILURE);

}

addr=shmat(shmid,0,0);

if(-1==*addr)

{

perror("shmat error:");

exit(EXIT_FAILURE);

}

while(1)

{

printf(" enter you height(CM) and height(KG):\n");

scanf("%f%f",addr,addr+1);

*(addr+2)=flag;

if(*addr==0||*(addr+1)==0 ) break; //if 输入其中一个的为0,跳出循环结束程序

}

return 0;

}

源文件2:

#include<stdio.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include<stdlib.h>

int main(int argc ,char *argv[])

{

int shmid;

float *addr;

float h,w;

shmid= shmget(ftok("./file",1000),getpagesize(), 0666);

if(shmid==-1)

{

perror("shmget error:");

exit(EXIT_FAILURE);

}

addr =shmat(shmid,0,0);

if(-1== *addr)

{

perror("shmat error:");

exit(EXIT_FAILURE);

}

while(1)

{

if(*(addr+2)!=1.0) //如果还没有输入新的数据那么就跳过此次循环,直到再次输入新的数据。

{

sleep(1);

continue;

}

*(addr+2)=0;

h=*addr;

w=*(addr+1);

if(h==0 || w==0) break; //if 输入其中一个的为0,跳出循环结束程序

int ret=w/(h*h/10000);

if(ret>=20 &&ret <=25)

{

printf("ok!\n");

}else if(ret <20)

{

printf("thin!\n");

} else

{

printf("fat!\n");

}

}

if(-1==shmdt(addr))

{

perror("shmdt error:");

exit(EXIT_FAILURE);

}

if (shmctl(shmid,IPC_RMID,0)==-1)

{

perror("shctl error:");

exit(EXIT_FAILURE);

}

return 0;

}

运行结果,当我们在一个终端上输入时,在另一个终端会打印出结果,而当我们输入0,0时两个都会退出.

Linux 进程间通讯(IPC)方式 ------- 共享内存相关推荐

  1. Linux进程间的通信----->共享内存

    共享内存:         顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物 ...

  2. linux进程间的通信(C): 共享内存

    一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的 ...

  3. linux无名管道实验代码,Linux 进程间通讯之创建无名管道和读写无名管道

    Linux进程间通讯的方式: 1. 管道(pipe)和有名管道(FIFO). 2. 信号(signal) 3. 消息队列 4. 共享内存 5. 信号量 6. 套接字(socket) 管道通讯: 无名管 ...

  4. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  5. Linux 进程间通讯方式 pipe()函数

    Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) 6-&g ...

  6. linux进程间通讯的几种方式的特点和优缺点,和适用场合。

    http://blog.csdn.net/kakaka2011/article/details/6636661 1. 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有 ...

  7. 【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap

    IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...

  8. linux命名管道进程间通信,Linux进程间通讯--命名管道

    IPC安全 前面总结了匿名管道,如今来看命名管道:因为匿名管道的一个限制就是:只能是有血缘关系的进程间才能够通讯,好比:有两个同祖先的子进程,父子进程等:为了突破这一个限制,想让没有任何关系的两个进程 ...

  9. linux进程间通讯-共享内存

    文章目录 共享内存概述 共享内存的特点 共享内存操作 在ubuntu 12.04中共享内存限制值如下 获得一个共享存储标识符 创建共享内存 共享内存映射(attach) 解除共享内存映射(detach ...

最新文章

  1. php 二维数组排序函数,php自定义二维数组排序函数array
  2. java 反射代价_Java反射机制
  3. 295. 数据流的中位数
  4. Android开发究竟该如何学习,附架构师必备技术详解
  5. Asp.NET 的几个高级技巧
  6. php每个月头一天与最后一天,PHP获取每月第一天与最后一天
  7. 使用扩展技术将SAP Fiori应用隐藏动态创建的UI字段
  8. 还在使用if else写代码?试试 “策略模式” 吧!
  9. 表数据都删了一半,可我的表文件咋还是那么大
  10. 动态参数 maven_Spring Security 动态url权限控制(三)
  11. 网站移动端500错误_PC网站和移动端网站有什么差异?
  12. 【零基础学Java】—Java 日期时间(三十一)
  13. rlocfind matlab,绘制根轨迹的MATLAB函数介绍
  14. html版权信息c怎么写,网页设计添加版权的语句肿么写
  15. Schwartz-Zippel Lemma
  16. 时间精力管理4象限法
  17. 零知识证明之 SnarkJS 入门
  18. bt5使用教程----渗透方面
  19. 常用激活函数及其原理/应用,以及相关的问题
  20. python中x、y=y、x_浅谈 (x, y) = (y, x)

热门文章

  1. unbantu安装 mysql --- 百度云
  2. 关于使用UIWebView加载HTTPS站点
  3. Fragment问题集
  4. 精确的力量:完美SNES仿真器的一个3GHz追求
  5. FSR 是提高性能和视觉效果
  6. InfoWorld 公布开源软件( 2019 年)
  7. MVC-JDBC的工作流程
  8. uni-app 行内样式动态背景图 :style 绑定
  9. zookeeper的acl权限控制_zookeeper权限acl与四字命令
  10. 滑动验证码研究-后续