共享内存相关函数

获得一个共享存储标识符

#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共享内存的更多相关文章

  1. Linux IPC 共享内存

    共享内存 共享内存(shared memory)是最简单的Linux进程间通信方式之一. 使用共享内存,不同进程可以对同一块内存进行读写. 由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不 ...

  2. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...

  3. linux 下共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

  4. linux 进程间通信 共享内存 shmat

    系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是通过shm ...

  5. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  6. 学习笔记:Linux下共享内存的方式实现进程间的相互通信

    一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...

  7. linux 进程间通信 共享内存 mmap

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...

  8. IPC——共享内存

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

  9. linux使用共享内存通信的进程同步退出问题

    两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...

随机推荐

  1. paper 147:Deep Learning -- Face Data Augmentation(一)

    1. 在深度学习中,当数据量不够大时候,常常采用下面4中方法:  (1)人工增加训练集的大小. 通过平移, 翻转, 加噪声等方法从已有数据中创造出一批"新"的数据.也就是Data ...

  2. paper 141:some paper with ComputerCV、MachineLearning[转]

    copy from:http://blog.csdn.net/zouxy09/article/details/8550952 一.特征提取Feature Extraction: ·         S ...

  3. LUOGU P2617 Dynamic Rankings(树状数组套主席树)

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  4. [MySQL] 怎样使用Mysqlcheck来检查和修复, 优化表

    mysqlcheck 是 MySQL 自带的一个工具,作用就是保养 表,其实就是检查,分析,修复和优化了.下面来介绍 mysqlcheck 工具的简单使用,官方文档在这里 原文网址:http://bl ...

  5. Java奇葩笔试题

    1.下面代码中,在if处填写什么代码,可以使得输出结果为:AB 1 2 3 4 5 6 7 8 9 public static void main(String[] args) { if ( ){// ...

  6. Arduino入门套件 Arduino UNO R3

    限时大抢购:原价5.6元超声波模块HC-SR04,现只需3元,亏本大甩卖,只赚人气,如需购买的客户请直接拍下以下链接3件=3元购买,备注超声波模块即可,每个客户ID每天仅限购一个.http://det ...

  7. 三.通过jenkins对系统的监控(2)

    在这记录下,通过HTTP Request Plugin监控系统的异常.和上一篇原理差不多. 1.首先需要安装HTTP Request Plugin.插件安装好后,在系统设置下面会新增如下配置: 具体有 ...

  8. 改进持续交付中的CI环节

    改进持续交付中的CI环节 在当前 DevOps 的趋势下,持续集成(CI)和持续部署(CD)具有支柱性地位,那么能够成功搭建 CI/CD 流水线就至关重要了. 今天我就讲一讲如何做好CI部分,让我们的 ...

  9. mybatis PageBounds应用分页

    第一步:分页工具类 package com.smartmorse.vo; import java.util.HashMap; import java.util.List; import java.ut ...

  10. SQL之in和like的连用实现范围内的模糊查询

    我们知道in可以实现一个范围内的查询,like可以实现模糊查询, 如 select *where col like 123%但是我们如果有一列attri,如123,132,165... 我们想实现12 ...