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 ...
随机推荐
- iOS设计模式之组合模式
组合模式(Composite) 基本理解 整体和部分可以一直对待. 组合模式:将对象组合成树形结构以表示"部分--整体"的层次结构.组合模式使得用户对单个对象和组合独享的使用具有一 ...
- Android Service使用拾遗[阿里工程师分享]
Service作为android的四大组件之一常用来帮助我们完成一些需要放在后台处理的任务,通过startService和bindService两种方式被调用.因为Service也是在主线程中运行的, ...
- OC中结构体作为对象属性
在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...
- x-forwarded-for的深度挖掘
转自:http://www.cnblogs.com/yihang/archive/2010/12/19/1910365.html 如今利用nginx做负载均衡的实例已经很多了,针对不同的应用场合,还有 ...
- MYSQL界面操作系统之phpMyAdmin
linux下: 需要PHP环境支持,安装PHP自行百度 下载linux-phpMyAdmin,并解压 php -S 127.0.0.1:8081 -t phpMyAdmin/
- C# Socket和TCP连接的区别
网络通信七层参考模型介绍: 物理层: HUB,网线 链路层: MAC,ARP,交换机 网络层:IP,ICMP,IGMP,路由器 传输层: TCP,UDP 会话层: HTTP,SMTP,FTP,POP3 ...
- js中location.href的用法
Javascript中的location.href有很多种用法,主要如下: self.location.href="/url" 当前页面打开URL页面 ocation.href=& ...
- 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)
关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...
- QQ JS省市区三级联动
如下图: 首先写一个静态的页面: <!DOCTYPE html> <html> <head> <title>QQ JS省市区三级联动</title ...
- Reverse Bits
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...