System V共享内存
1. 概述
System V共享内存在概念上类似于Posix共享内存,代之以调用shm_Open后调用mmap的是,先调用shmget,再调用shmat。
对于每个System V共享内存,内核都维护如下的信息结构,它定义在sys/shm.h头文件中,其中带注释的是我们需要关注的成员。
struct shmid_ds
{
struct ipc_perm shm_perm;
size_t shm_segsz; //共享内存区大小
pid_t shm_lpid;
pid_t shm_cpid;
shmatt_t shm_nattch;
shmat_t shm_cnattch;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
};
2. System V共享内存API
shmget
shmget用于创建一个新的共享内存或打开一个已存在的共享内存。
//成功返回共享内存标识符,
int shmget(key_t key, size_t size, int oflag);
- 参数size是共享内存区大小,其余两个参数含义及用法和System V信号量一样
- 当实际操作为创建新的共享内存时,该内存区size个字节均被初始化为0
- 当实际操作为打开已有共享内存时,size可设为0,oflag设为需要的读写权限
shmat
shmat用于把shmget创建或打开的共享内存连接到调用进程的地址空间。
//成功返回映射区起始地址,失败返回-1
void *shmat(int shmid, const void *shmaddr, int flag);
- shmid是shmget返回的标识符
- shmaddr推荐设为NULL,表示由系统决定映射区起始地址
- flag一般设为0,因为只要调用进程具有共享内存的读写权限,那么映射区内存就也可以读写
- flag也可以设为SHM_RDONLY限定只读访问
shmdt
shmdt删除由shmat建立的连接。
//成功返回0,失败返回-1
int shmdt(const void *shmaddr);
shmctl
shmctl用于对共享内存的各种控制操作。
//成功返回0,失败返回-1
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
cmd可使用的命令有三个:
- IPC_RMID:从系统中删除共享内存,此时buf参数设为NULL即可
- IPC_STAT:通过buf返回共享内存对应的shmid_ds结构,一般用此命令获取共享内存区大小
- IPC_SET:通过buf设置共享内存对应shmid_ds结构中的shm_perm.uid、shm_perm.gid和shm_perm.mode
3. 简单的程序
代码实现
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define FTOK_FILE "/home/delphi/ftok.file"
#define FTOK_ID 1
#define SHM_RD_PERMISSION 0444
#define SHM_WR_PERMISSION 0222
#define SHM_RW_PERMISSION (SHM_RD_PERMISSION | SHM_WR_PERMISSION)
#endif
shmcreate.c
#include "common.h"
int main(int argc, char **argv)
{
int length = atoi(argv[1]);
int oflag = IPC_CREAT | SHM_RW_PERMISSION;
int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), length, oflag);
if (shmid >= 0)
{
printf("shmget create success, shmid = %d\n", shmid);
}
return 0;
}
shmrmid.c
#include "common.h"
int main(int argc, char **argv)
{
int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
shmwrite.c
#include "common.h"
int main(int argc, char **argv)
{
int shmid;
unsigned char *shmadd;
struct shmid_ds buf;
int i;
shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
shmadd = shmat(shmid, NULL, 0);
shmctl(shmid, IPC_STAT, &buf);
for (i = 0; i < buf.shm_segsz; i++)
{
*shmadd++ = i % 256;
}
return 0;
}
shmread.c
#include "common.h"
int main(int argc, char **argv)
{
int shmid;
unsigned char *shmadd;
unsigned char v;
struct shmid_ds buf;
int error = 0;
int i;
shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
shmadd = shmat(shmid, NULL, 0);
shmctl(shmid, IPC_STAT, &buf);
for (i = 0; i < buf.shm_segsz; i++)
{
v = *shmadd++;
if (v != (i % 256))
{
printf("error: shmadd[%d] = %d\n", i, v);
error++;
}
}
if (error == 0)
{
printf("all of read is ok\n");
}
return 0;
}
代码测试
System V共享内存的更多相关文章
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- 阐述linux IPC(五岁以下儿童):system V共享内存
[版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途] system V共享内存和posix ...
- UNIX环境高级编程——System V 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...
- php进程(线程)通信基础--System V共享内存
PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项 System V消息,--enable-sysvmsg System V信号量支持,--enable-sysvsem ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- 共享内存之——system V共享内存
System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...
- Linux system v 共享内存
system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...
随机推荐
- 查看 redis 请求日志
转: 查看 redis 请求日志 2019-05-29 15:34:41 打卤 阅读数 1980更多 分类专栏: other 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转 ...
- 深入理解Flink ---- 系统内部消息传递的exactly once语义
At Most once,At Least once和Exactly once 在分布式系统中,组成系统的各个计算机是独立的.这些计算机有可能fail. 一个sender发送一条message到rec ...
- 如何杀死处于进程状态D的进程
D状态的就是 uninterruptible sleep ,此时进程不能被信号唤醒,GDB等调试工具也不能对它调试,因为GDB也是用到了信号,也杀不死它 D状态的形成 如何分析D状态 cat /pro ...
- grok语法定义
grok默认表达式 Logstash 内置了120种默认表达式,可以查看patterns,里面对表达式做了分组,每个文件为一组,文件内部有对应的表达式模式.下面只是部分常用的. 常用表达式 表达式标识 ...
- LeetCode 240. 搜索二维矩阵 II(Search a 2D Matrix II) 37
240. 搜索二维矩阵 II 240. Search a 2D Matrix II 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性 ...
- 在Jenkins的pipeline项目中运行jmeter测试-教程
Jenkins 2.0的发布引入了一种新的项目类型 - Pipeline,以前只能通过插件获得.从Jenkins 2.0开始,Pipeline项目开箱即用. 与通常的“自由式”项目相比,管道构建具有几 ...
- FZU2018级算法第一次作业 1.1fibonacci (矩阵快速幂)
题目 Winder最近在学习fibonacci 数列的相关知识.我们都知道fibonacci数列的递推公式是F(n)=F(n-1)+F(n-2)(n>=2 且n 为整数). Winder想知道的 ...
- python基础 — 文件操作
读取键盘输入 Python提供了两个内置函数从标准输入读入一行文本,默认的标准输入是键盘.如下: raw_input input raw_input函数 raw_input([prompt]) 函数从 ...
- InfoGan笔记
InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets ...
- 方法1:使用Jenkins构建Docker镜像 --SpringCloud
前提意义: SpringCloud微服务里包含多个文件夹,拉取仓库的所有代码,然后过根据选项参数使用maven编译打包指定目录的jar,然后再根据这个目录的Dockerfile文件制作Docker镜像 ...