Linux 进程通信(共享内存区)
共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段)。
如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中。
如果一个进程更新了段中的数据,其他进程也立即会看到更新。
由一个进程创建的段,也可以由另一个进程读写。
每个进程都把它自己对共享内存的映像放入自己的地址空间。
创建共享内存区
int shmget(key_t key,size_t size,int shm-flg);
参数key既可以是IPC_PRIVATE(IPC_PRIVATE表示让系统分配一个Key),也可以是ftok函数返回的一个关键字。
参数size指定段的大小。
参数flgs--八进制数,,转化为二进制后分别代表rw-rw-rw-
shmget成功返回段标识符,失败返回-(一般不会创建失败,除非系统没有内存).
注意:只有创建权限是0666的才可以用命令行"ipcs -m"查看,其他类型权限的共享内存区无法被这个命令所查看。
//创建共享内存
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h> #include <sys/ipc.h>
#include <sys/shm.h> int main(int arg, char *args[])
{
int shmid=shmget(IPC_PRIVATE,sizeof(char)*,);
if(shmid==-)
{
printf("error\n");
return -;
}
printf("创建共享内存成功!内存段标识符是%d\n",shmid);
return ;
}
在命令行执行"ipcs -m "显示已经成功的创建了一块共享内存区。
nattch字段显示已经附加到这个内存区的进程数。
附加共享内存区
void * shmat(int shmid,void * shmaddr,int shmflg);
int shmdt(const * void shmaddr);
参数shmid是要附加的共享内存区标识符(在命令行执行ipcs -m 显示)。
总是把参数shmaddr设为0,0表示系统会自动在被附加的进程内创建一个内存段,映射到共享内存区。当然也可以指定一个被附加的进程内的一块内存,但是需要用户自己malloc分配内存,并将地址传给shmaddr参数,比较麻烦,一般使用系统自动分配。
参数shmflg可以为SHM_RDONLY,这意味着附加段是只读的,参数为0时,表示可以读写。
shmat成功返回被附加了段的地址,失败返回-,并设置errno,虽然返回值是指针类型,但是返回的的确是-1。
函数shmdt是将附加在shmaddr的段从调用进程的地址空间分离出去,这个地址必须是shmat返回的(即从自己进程内释放被附加的共享内存,强调不是释放系统的那个共享内存)。
注意:进程里附加共享内存区的大小一定是和系统共享内存一样大,为了方便映射(两块内存不一样大如何同步数据?)。
//创建附加共享内存
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h> #include <sys/types.h>
#include <sys/shm.h> int main(int arg, char *args[])
{
if (arg < )
{
printf("请输入2个参数!\n");
return -;
}
int flag = ;
int shmid = ;
shmid = atoi(args[]);
flag = atoi(args[]);
//创建本进程被附加的共享内存
void * shmbuf = NULL;
shmbuf = shmat(shmid, , );
/*
编译警告:warning: cast from pointer to integer of different size
这句警告意思是指针类型大小和Int类型大小不同,根据以前的知识,指针都是4个字节大小,
其实指针的大小不是固定的4个字节。32位cpu的计算机上是4字节,64位cpu的计算机上是8个字节。
这是因为32位计算机中的地址是32位的(可以在32位系统下查看指针的值例如--0x003bf9a3)
但是在64位计算机中地址是64位的(可以在64位系统下查看指针的值例如--0xffffffffffffffff)
十六进制数字的1位等于二进制的4位
虽然指针的值在32位系统和64位系统中有区别,但是一个字节的大小在两个系统中是相同的,
举例说Int类型数据,不管是在32位系统和64位系统中都在内存中占据4个字节大小的内存空间
*/
if ((int) shmbuf == -)
{
printf("创建附加共享内存区失败!error message:%s\n", strerror(errno));
return -;
}
sleep();
if (flag == )
{
//将数据写入本进程自己的附加共享内存区
//这里系统共享内存区的大小是1kb
read(STDIN_FILENO, shmbuf, sizeof(char) * );
} else if (flag == )
{
printf("%s", shmbuf);
}
return ;
}
shmdt函数
--功能:将共享内存段与当前进程脱离
--参数
shmarr:由shmat所返回的指针
--返回值:成功返回0,失败返回-
--注意:将共享内存段与当前进程脱离不等于删除共享内存
释放共享内存区
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数shmid是共享内存区段标识符,
参数cmd一般有三个值IPC_STAT(获取共享内存区的状态,由第三个参数获取状态),IPC_SET(设置共享内存区),IPC_RMID(删除共享内存区,此时第三个参数一般传0);
shmctl成功返回0,失败返回-,并且设置errno的值
//创建共享内存区
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h> int main(int arg,char * args[])
{
if(arg<)
{
printf("请输入一个参数!\n");
return -;
}
int shmid=atoi(args[]);
int flag=shmctl(shmid,IPC_RMID,);
if(flag<)
{
printf("error message:%s\n",strerror(errno));
return -;
}
printf("返回值是%d\n",flag);
return ;
}
命令行释放共享内存区
在命令行执行"ipcrm -m shmid" 或者 "ipcrm shm shmid"
Linux 进程通信(共享内存区)的更多相关文章
- Linux学习笔记(14)-进程通信|共享内存
在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...
- Windows进程通信 -- 共享内存(1)
共享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信.因为是通过内存操作实现通信,因此是一种最高效的数据交换方法. 共享内存在 W ...
- Windows进程通信 -- 共享内存
享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信.因为是通过内存操作实现通信,因此是一种最高效的数据交换方法. 共享内存在 Wi ...
- Windows进程通信-共享内存空间
三个模块 1,game.exe,三个方法,控制台输入指令('A','B','R')分别控制三个方法的调用: 2,WGDll.dll,要注入到game进程中的dll文件: 3,myconsole.exe ...
- linux 进程间共享内存示例
写入端: #include <iostream> #include <unistd.h> #include <stdlib.h> #include <stdi ...
- linux 进程通信之 共享内存
共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法.一个进程向共享内存区域写入了数据,共享这个内存区域的全部进程就能够立马看到当中的内容. 关于共享内存使用的API k ...
- Linux环境编程之共享内存区(一):共享内存区简单介绍
共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进 ...
- Posix共享内存区
1.概述 Posix提供了两种在无亲缘关系进程间共享内存区的方法: (1)内存映射文件:先有open函数打开,然后调用mmap函数把得到的描述符映射到当前进程地址空间中的一个文件(上一篇笔记所用到的就 ...
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
随机推荐
- JAVA基础学习day25--Socket基础二-多线程
一.上传图片 1.1.示例 /* 上传图片 */ import java.net.*; import java.io.*; import java.util.*; import java.text.* ...
- C++中const用法总结
1修饰变量/指针 注意以下几种修饰的区别: (1)const int * a; (2)int const *a; (3)int * const b; (4)int const* const c; 其中 ...
- 解决log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader)警告信息的问题
spring项目经常在启动tomcat时报如下警告信息: log4j:WARN No appenders could be found for logger (org.springframework. ...
- 命令行方式使用abator.jar生成ibatis相关代码和sql语句xml文件
最近接手一个老项目,使用的是数据库是sql server 2008,框架是springmvc + spring + ibatis,老项目是使用abator插件生成的相关代码,现在需要增加新功能,要添加 ...
- 算法(二)之遗传算法(SGA)
算法(二)之遗传算法(SGA) 遗传算法(Genetic Algorithm)又叫基因进化算法或进化算法,是模拟达尔文的遗传选择和自然淘汰的生物进化过程的计算模型,属于启发式搜索算法一种. 下面通过下 ...
- maven 仓库搜索添加需要的jar包
可用仓库网址: http://search.maven.org/#browse http://mvnrepository.com/ http://repository.sonatype.org/ind ...
- 对于这个函数const int func(const int& a) const声明中,三个const分别是什么意思?
第一个const 函数的返回值类型是const. 这个const修饰没什么意义,你可以想象一下: 既然是函数的 返回值,而且是值传递的形式,是否const有什么意义.如果指针(引用)传递,怎表示返回值 ...
- APP 接口开发及读取静态缓存
<?php /** * Description: App 接口 * Create date:2015-10-19 13:36 * Author: zhaoyingnan **/ class Re ...
- Android 开发框架
Android 开发框架包括基本的应用功能开发.数据存储.网络访问三大块. 1 应用方面 一般而言,一个标准的Android 程序包括Activity.Broadcast Intent Receive ...
- Solr Dataimporthandler 导入MySQL 内存溢出。
最近准备把一千九百多万数据导入Solr中,在以前测试数据只有一两百万,全量导入没有任务问题.但是,换成一千九百万数据时,solr报内存异常(java.lang.OutOfMemoryError:GC ...