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)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...
随机推荐
- 【JZOJ1913】【BZOJ2124】等差子序列
description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<-<pLen<=N (Len>=3), 使得A ...
- youlexuan父类配置
<!-- 集中定义依赖版本号 --> <properties> <junit.version>4.12</junit.version> ...
- Python--基础之socket编程
一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...
- Spring 容器中bean的加载过程
bean 的加载过程大致可以分为以下几个步骤: 1.获取配置的资源文件 2.对获取到的xml资源文件进行解析 3.获取包装资源 4.解析处理包装之后的资源 5.加载 提取bean 并进行注册(添加到b ...
- centos6 sersync2使用
接收端rsyncd搭建 http://www.cnblogs.com/hanxiaohui/p/8675409.html 推送端sersync2使用 安装 源码包D:\share\src\sersyn ...
- undefined null测试
测试浏览器:chrome 当有父元素的子元素未定义时undefined和null均为true,类型为undefined 当元素赋给null后undefined和null均为true,类型为object ...
- DBA-io
- 危险,几条可致命的Linux命令!
1. rm -rf 命令 rm -rf命令是删除文件夹及其内容最快的方式之一.仅仅一丁点的敲错或无知都可能导致不可恢复的系统崩坏.下列是一些rm 命令的选项.rm 命令在Linux下通常用来删除文件. ...
- C++——运行时类型识别RTTI
1.实现方式 typeid运算符,返回表达式的类型 dynamic_cast运算符,基类的指针或引用安全地转换成派生类的指针或引用 2.适用于:使用基类的指针或引用执行派生类的操作,且该操作不是虚函数 ...
- PHP 遍历目录下面的所有文件及子文件夹
//遍历文件夹下面所有文件及子文件夹 function read_all_dir ( $dir ){ $result = array(); $handle = opendir($dir);//读资源 ...