共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区。在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一

个共享内存区的最大字节数shmmax,系统范围内最大共享内存区标识符数shmmni等,可以手工对其调整,但不推荐这样做。

一、应用

共享内存的使用,主要有以下几个API:ftok()、shmget()、shmat()、shmdt()及shmctl()。

1)用ftok()函数获得一个ID号.

应用说明:

在IPC中,我们经常用用key_t的值来创建或者打开信号量,共享内存和消息队列。

函数原型:

key_t ftok(const char *pathname, int proj_id);

Keys:

1)pathname一定要在系统中存在并且进程能够访问的

3)proj_id是一个1-255之间的一个整数值,典型的值是一个ASCII值。

当成功执行的时候,一个key_t值将会被返回,否则-1被返回。我们可以使用strerror(errno)来确定具体的错误信息。

考虑到应用系统可能在不同的主机上应用,可以直接定义一个key,而不用ftok获得:

#define IPCKEY 0x344378

2)shmget()用来开辟/指向一块共享内存的函数

应用说明:

shmget()用来获得共享内存区域的ID,如果不存在指定的共享区域就创建相应的区域。

函数原型:

int shmget(key_t key, size_t size, int shmflg);

key_t key

是这块共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。如果两个进程没有任何关系,所以就用ftok()算出来一个标识符(或者自己定义一个)使用了。

int size 是这块内存的大小.

int flag 是这块内存的模式(mode)以及权限标识。

模式可取如下值:

IPC_CREAT 新建(如果已创建则返回目前共享内存的id)

IPC_EXCL  与IPC_CREAT结合使用,如果已创建则则返回错误

然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。

如:  IPC_CREAT | IPC_EXCL |

0640

例子中的0666为权限标识,4/2/1

分别表示读/写/执行3种权限,第一个0是UID,第一个6(4+2)表示拥有者的权限,第二个4表示同组权限,第3个0表示他人的权限。

这个函数成功时返回共享内存的ID,失败时返回-1。

关于这个函数,要多说两句。

创建共享内存时,shmflg参数至少需要 IPC_CREAT | 权限标识,如果只有IPC_CREAT

则申请的地址都是k=0xffffffff,不能使用;

取已创建的共享内存时,shmflg不要用IPC_CREAT(只能用创建共享内存时的权限标识,如0640),否则在某些情况下,比如用ipcrm删除

共享内存后,用该函数并用IPC_CREAT参数获取一次共享内存(当然,获取失败),则即使再次创建共享内存也不能成功,此时必须更改key来重建共享

内存。

3) shmat()将这个内存区映射到本进程的虚拟地址空间。

函数原型:

void  *shmat( int shmid ,

char *shmaddr , int shmflag );

shmat()是用来允许本进程访问一块共享内存的函数。

int shmid是那块共享内存的ID。

char

*shmaddr是共享内存的起始地址,如果shmaddr为0,内核会把共享内存映像到调用进程的地址空间中选定位置;如果shmaddr不为0,内核会把共享内存映像到shmaddr指定的位置。所以一般把shmaddr设为0。

int shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式

成功时,这个函数返回共享内存的起始地址。失败时返回-1。

4)

shmdt()函数删除本进程对这块内存的使用,shmdt()与shmat()相反,是用来禁止本进程访问一块共享内存的函数。

函数原型:

int shmdt( char *shmaddr );

参数char *shmaddr是那块共享内存的起始地址。

成功时返回0。失败时返回-1。

5) shmctl() 控制对这块共享内存的使用

函数原型:

int  shmctl( int shmid ,

int cmd , struct shmid_ds *buf );

int shmid是共享内存的ID。

int cmd是控制命令,可取值如下:

IPC_STAT  得到共享内存的状态

IPC_SET  改变共享内存的状态

IPC_RMID  删除共享内存

struct shmid_ds

*buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。

返回值:  成功:0

失败:-1

接下去是两个demo

write部分

#include

#include

#include

#include

#include

typedef struct {

char name;

int age;

}people;

int main(void)

{

int shm_id,i;

key_t key;

people *p_map;

key =

ftok("/home/beichenming/class3",0);

if (key == -1)

{

perror("ftok error");

exit(1);

}

printf("key

%d\n",key);

shm_id = shmget(key,

2048,IPC_CREAT | IPC_EXCL | 0666);

if (shm_id == -1)

{

perror("shmget error");

exit(1);

}

printf("shm_id

%d\n",shm_id);

p_map =

(people*)shmat(shm_id, NULL, 0);

for (i = 0; i < 10;

i++)

{

p_map[i].name = 'a';

p_map[i].age = i;

}

shmdt(p_map);

return 0;

}

read部分

#include

#include

#include

#include

#include

#include

#include

typedef struct {

char

name;

int

age;

}people;

int main(void)

{

int shm_id,i;

key_t key;

people *p_map;

key =

ftok("/home/beichenming/class3",0);

if (key == -1)

{

perror("ftok error");

exit(1);

}

printf("key

%d\n",key);

shm_id =

shmget(key,0,0);

if (shm_id == -1)

{

perror("shmget error");

exit(1);

}

printf("shm_id

%d\n",shm_id);

p_map =

(people*)shmat(shm_id, NULL, 0);

for (i = 0; i < 10 ;

i ++)

{

printf("name %c\n",p_map[i].name);

printf("age %d\n",p_map[i].age);

}

return 0;

}

代码下载地址

ipc_write.c : http://pan.baidu.com/s/13maGp

ipc_read.c:

http://pan.baidu.com/s/1GJmaU

c语言中shmget相关函数,unix中共享内存(shmget的实现,非mmap)相关推荐

  1. c语言中math的库函数,C语言中math.h库中的常用函数

    C语言中math.h库中的常用函数 int abs(int i) 返回整型参数i的绝对值 double cabs(struct complex znum) 返回复数znum的绝对值 double fa ...

  2. main c语言中变量的定义,C语言中在main函数中定义的变量是全局变量么_后端开发...

    PHP 和 JavaSript 区别_后端开发 PHP是一种创建动态交互性站点的强有力的服务器端脚本语言,主要用于Web开发领域,而JavaSript是一种具有函数优先的轻量级,解释型或即时编译型的高 ...

  3. 共享内存shmget的郁闷

    今天上午试验共享内存 shmget,但是总是不能成功申请到内存. 一开始还以为是第一个参数key有问题,调试了半天,发现key是正确的,没有报错,也可以根据不同路径变化. key_t ftok(con ...

  4. linux获取共享内存失败2,unix/linux共享内存应用与陷阱

    共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区.在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一 个共享内存区的最大字节数shmmax,系统范围内最大共享内存 ...

  5. shmget物理内存_Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()...

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

  6. 共享内存---shmget shmat shmdt

    From: http://fengxue103.blog.hexun.com/32303320_d.html 要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使 ...

  7. linux 共享内存 shmget

    专栏内容:linux下并发编程 个人主页:我的主页 座右铭:天行健,君子以自强不息:地势坤,君子以厚德载物. 目录 前言 概述 原理机制 系统命令 接口说明 代码演示 结尾 前言 本专栏主要分享lin ...

  8. 共享内存 shmget函数

    内核共享内存 shmget 头文件 函数 #include <sys/ipc.h> #include <sys/shm.h>// 得到一个共享内存标识符或创建一个共享内存对象并 ...

  9. Linux 3.进程间通信(shmget shmat shmdt shmctl 共享内存、signal signaction sigqueue 信号、semget semctl semop 信号量)

    Linux 3.进程间通信(IPC) 共享内存 共享内存的接口指令 shmget 创建获取获取共享内存 shmat 映射:连接共享内存到当前进程的地址空间 shmdt 断开与共享内存的连接 shmct ...

最新文章

  1. 多项式相乘快速算法原理及相应C代码实现
  2. 《网站性能监测与优化》一2.4 软件服务应用网站
  3. 问题解决:java.sql.SQLException:Value '0000-00-00' can not be represented as java.sql.Date
  4. 工程计算软件_软件工程师的计算机基础理论知识体系
  5. 曲线拟合的线性最小二乘法
  6. CentOS上安装man手册
  7. 第一次自己成功写成的js程序
  8. 494. Target Sum
  9. python手写输入法开发_QT 手写输入法 - 程序员狗蛋的个人空间 - OSCHINA - 中文开源技术交流社区...
  10. Mouse Without Borders 使用经验
  11. Java抓取网页图片
  12. adb命令模拟按键事件 KeyCode
  13. 微博数据:如何在西瓜微数平台使用「热门话题分析」功能?
  14. 计算机管理磁盘管理右键无反应,win7系统删除磁盘管理磁盘右键菜单只有“帮助”的解决技巧...
  15. 【unity 保卫星城】--- 开发笔记08(UI轮盘)
  16. Springboot具有智能推荐功能的外卖点餐系统bia14计算机毕业设计-课程设计-期末作业-毕设程序代做
  17. python控件_python控件怎么用
  18. 博客系统项目:设计篇
  19. CANoe:CAPL周期发送CANFD报文
  20. 抖音表情包项目怎么变现?普通人如何制作表情包短视频月入过万?

热门文章

  1. 面试 10、自我认知能力
  2. 终身学习(LifeLong Learning)/ 增量学习(Incremental Learning)、在线学习(Online Learning)
  3. kernel something
  4. 软件测试设计测试用例方法
  5. 数据检索的玄铁剑——索引
  6. js设置单选框为选中状态
  7. goland 插件管理_GoLand 使用SVN
  8. 查看linux java目录,linux 查看java安装目录
  9. C语言空白符、空格符 与转义字符题点总结
  10. 数据库:存储过程实验