linux IPC共享内存
共享内存相关函数
获得一个共享存储标识符
#include <sys/ipc.h>
#include <sys/shm.h int shmget(key_t key, size_t size, int shmflg);
返回值:成功共享存储ID,失败-
key:函数ftok返回值或IPC_PRIVATE(适合用在有亲缘关系的进程中) size: 共享存储段的长度,以字节为单位
shmflg:权限标志位
共享存储段执行多种操作
#include <sys/ipc.h>
#include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);
返回值:成功0错误-
shmid:共享内存标识符
cmd: IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode赋值到共享内存的shmid_ds结构中
IPC_RMID:删除这些共享内存
buf:共享内存管理结构体
shmid_ds结构:
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
struct shmid_ds
一旦创建了一个共享存储段,进程就可调用shmat将其连接到它的地址空间中
#include <sys/types.h>
#include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);
返回值:成功共享存储段的指针,失败-
shmid:共享内存标识符
shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核决定
shmflg:如果指定了SHM_RDONLY位,则以只读方式连接此段,否则以读写的方式连接此段。通常为0
当对共享存储段的操作已经结束时,则调用shmdt与该段分离
#include <sys/types.h>
#include <sys/shm.h> int shmdt(const void *shmaddr);
返回值:成功0,失败-
shmaddr:shmat返回的值
程序例程,父子进程间通讯:
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h> #define SIZE 1024 int main()
{
int shmid;
pid_t pid;
char *shmaddr;
int flag;
struct shmid_ds buf; shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT|);
if(shmid < )
{
perror("get shm ipc_id error");
return -;
} if((pid = fork()) < ) {
perror("get fork error");
return -;
} else if(pid == ) { /* child */
shmaddr = (char *)shmat(shmid, NULL, );
if((int)shmaddr == -)
{
perror("shmat error");
return -;
}
strcpy(shmaddr, "Hi,I am child process!\n");
shmdt(shmaddr);
return ;
} else { /* parent */
sleep();
flag = shmctl(shmid, IPC_STAT, &buf);
if(flag == -)
{
perror("shmctl error");
return -;
} printf("shm_segsz=%d bytes\n", buf.shm_segsz);
printf("parent pid=%d,shm_cpid=%d \n", getpid(), buf.shm_cpid);
printf("child pid=%d,shm_lpid=%d\n", pid, buf.shm_lpid);
shmaddr = (char *)shmat(shmid, NULL, );
if((int)shmaddr == -)
{
perror("parent:shmat error");
return -;
}
printf("shmaddr in %s\n", shmaddr);
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
} return ;
}
进程之间使用共享内存通讯:
shmwrite.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h> typedef struct {
char name[];
int age;
}people; int main()
{
int shmid;
key_t key;
char temp[];
char pathname[];
people *p_map;
int i; strcpy(pathname, "/tmp");
key = ftok(pathname, 0x03);
if(key == -)
{
perror("ftok error\n");
return -;
} printf("key=%d\n", key);
shmid = shmget(key, ,IPC_CREAT|IPC_EXCL|);
if(shmid == -)
{
perror("shmget error\n");
return -;
}
printf("shmid=%d\n",shmid); p_map = (people *)shmat(shmid, NULL, );
if((int)p_map == -)
{
perror("shmat error\n");
return -;
}
memset(temp, 0x00, sizeof(temp));
strcpy(temp, "test");
temp[] = ''; for(i=;i<;i++)
{
temp[]+=;
strncpy((p_map+i)->name, temp, );
(p_map+i)->age=i;
} if(shmdt(p_map) == -)
{
perror("shmdt error\n");
return -;
}
return ;
}
shmread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct {
char name[];
int age;
}people; int main(int argc, char *argv[])
{
int shmid;
people *p_map;
key_t key;
char pathname[];
int i = ; strcpy(pathname, "/tmp");
key = ftok(pathname, 0x03);
if(key == -)
{
perror("ftok error\n");
return -;
}
printf("key=%d\n", key);
shmid = shmget(key, , );
if(shmid == -)
{
perror("shmread:shmget error\n");
return -;
}
printf("shmid=%d\n",shmid);
p_map = (people*)shmat(shmid, NULL, );
for(i=;i<;i++)
{
printf("name:%s\n", (*(p_map+i)).name);
printf("age:%d\n", (*(p_map+i)).age);
}
if(shmdt(p_map) == -)
{
perror("shmdt error\n");
return -;
}
return ;
}
然后执行:
gcc shmwrite.c -o shmwrite
gcc shmread.c -o shmread
./shmwrite
./shmread
linux IPC共享内存的更多相关文章
- Linux IPC 共享内存
共享内存 共享内存(shared memory)是最简单的Linux进程间通信方式之一. 使用共享内存,不同进程可以对同一块内存进行读写. 由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不 ...
- Linux进程间通信—共享内存
五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...
- linux 下共享内存
一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...
- linux 进程间通信 共享内存 shmat
系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是通过shm ...
- linux下共享内存mmap和DMA(直接访问内存)的使用 【转】
转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...
- 学习笔记:Linux下共享内存的方式实现进程间的相互通信
一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...
- linux 进程间通信 共享内存 mmap
共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...
- IPC——共享内存
Linux进程间通信——使用共享内存 下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的 ...
- linux使用共享内存通信的进程同步退出问题
两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...
随机推荐
- css雪碧图实现数字切换
vue中 css 雪碧图应用及数字切换demo 1. CSS Sprites一般只能使用到固定大小的盒子(box)里,这样才能够遮挡住不应该看到的部分. 2.使用css雪碧图的优点: 利用CSS Sp ...
- 职责链模式ChainOfResponsibility
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11407114.html 1.定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合 ...
- 【集群】Redis集群设计原理
Redis集群设计包括2部分:哈希Slot和节点主从 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读写分离,直接上图: 图上能看得到的信息: 1, 只有1个Master,可以有 ...
- BZOJ 2301 莫比乌斯反演入门
2301: [HAOI2011]Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函 ...
- windows 下redis在后台运行
打开命令终端,cd进入redis目录 安装redis服务:redis-server --service-install redis.windows.conf --loglevel verbose re ...
- CSS 的基础语法
1.基础语法规则 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. 每条声明由一个属性和一个值组成.每个属性有一个值.属性和值被冒号分开. selector {property: val ...
- [CSP-S模拟测试45]题解
开局一行$srand$,得分全靠随机化. A.kill 发现两个并不显然的性质: 1.选中的人和怪物一定是按顺序的.第一个人打所有被选中怪物的第一只,第二个人打第二只,$etc$. 2.最优方案打的怪 ...
- Migrating Your Android App from Eclipse to Android Studio
By: Jason Snell | Posted in: Mobile, Performance Tech Tips, Top Post, Jun. 7th, 2013 12 inShare One ...
- if语句里面continue和break的区别
break:结束整个循环体 continue:结束本次循环 代码说明: public static void main(String[] args) { int x=0; while(x++ < ...
- 力扣算法——136SingleNumber【E】
Given a non-empty array of integers, every element appears twice except for one. Find that single on ...