第三十五章 POSIX共享内存
POSIX共享内存函数介绍
shm_open
功能:
用来创建或打开一个共享内存对象
原型:
int shm_open(const char *name, int oflag, mode_t mode);
参数:
name : 共享内存对象的名字(命名规则和POSIX消息队列一样)
oflag :与open函数类似,可以是O_RDONLY、O_WRONLY、O_RDWR,还可以按位或上O_CREAT、O_EXCL、O_TRUNC等
mode : 此参数总是需要设置,如果oflag没有指定O_CREAT,可以指定为0
返回值:
成功 : 成功返回非负整数文件描述符
失败 : -1
ftruncate
功能:
修改共享内存的大小(还可以用来修改文件的大小)
原型:
int ftruncate(int fd, off_t length);
参数:
fd : 文件描述符
length :长度
返回值:
成功 : 0
失败 : -1
fstat
功能:
获取共享内存对象信息(还可以用来获取文件的信息)
原型:
int fstat(int fd, struct stat *buf);
参数:
fd : 文件描述符
buf :返回共享内存状态
返回值:
成功 : 0
失败 : -1
shm_unlink
功能:
删除共享内存对象
原型:
int shm_unlink(const char *name);
参数:
name : 共享内存对象的名字
返回值:
成功 : 0
失败 : -1
mmap
功能:
将共享内存对象映射到进程地址空间
原型:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
参数:
addr : 要映射的起始地址,通常指定为NULL,让内核自动选择
length : 映射到进程地址空间的字节数
prot : 映射区保护方式
flags : 标志
fd : 文件描述符
offset : 从文件头开始的偏移量
返回值:
成功 : 成功返回映射到的内存的起始地址
失败 : -1
POSIX共享内存示例
共享内存已经自动挂载到/dev/shm目录下
shm_open.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <sys/types.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct stu{
char name[32];
int age;
}STU;
int main(int argc, char const *argv[])
{
int shmid;
//创建一个共享内存
//创建的时候指定的权限是0666,创建后不一定是666,它还取决于umask,公式 mode & ~umask
shmid = shm_open("/xyz", O_CREAT|O_RDWR, 0666);
if(shmid == -1)
ERR_EXIT("shm_open");
printf("shm_open success\n");
//改变共享内存的大小
if(ftruncate(shmid,sizeof(STU)) == -1)
ERR_EXIT("ftruncate");
//获取共享内存的信息
struct stat buf;
if(fstat(shmid, &buf) == -1)
ERR_EXIT("fstat");
printf("size : %ld mode : %o\n",buf.st_size, buf.st_mode & 0777);
close(shmid);
return 0;
}
shm_write.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <sys/types.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct stu{
char name[32];
int age;
}STU;
int main(int argc, char const *argv[])
{
int shmid;
//创建一个共享内存
shmid = shm_open("/xyz", O_RDWR, 0);
if(shmid == -1)
ERR_EXIT("shm_open");
printf("shm_open success\n");
//获取共享内存的信息
struct stat buf;
if(fstat(shmid, &buf) == -1)
ERR_EXIT("fstat");
STU *p;
//如果指定了PROT_WRITE和MAP_SHARED,shm_open的oflag应该指定为O_RDWR,否则会出现mmap: Permission denied
p = mmap(NULL, buf.st_size, PROT_WRITE, MAP_SHARED, shmid, 0);
if(p == MAP_FAILED)
ERR_EXIT("mmap");
strcpy(p->name, "test");
p->age = 20;
close(shmid);
return 0;
}
shm_read.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <sys/types.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct stu{
char name[32];
int age;
}STU;
int main(int argc, char const *argv[])
{
int shmid;
//创建一个共享内存
shmid = shm_open("/xyz", O_RDONLY, 0);
if(shmid == -1)
ERR_EXIT("shm_open");
printf("shm_open success\n");
//获取共享内存的信息
struct stat buf;
if(fstat(shmid, &buf) == -1)
ERR_EXIT("fstat");
STU *p;
//如果指定了PROT_WRITE和MAP_SHARED,shm_open的oflag应该指定为O_RDWR,否则会出现mmap: Permission denied
p = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, shmid, 0);
if(p == MAP_FAILED)
ERR_EXIT("mmap");
printf("name : %s\n", p->name);
printf("age : %d\n", p->age);
close(shmid);
return 0;
}
shm_unlink.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
int main(int argc, char const *argv[])
{
shm_unlink("/xyz");
return 0;
}
第三十五章 POSIX共享内存的更多相关文章
- Gradle 1.12用户指南翻译——第三十五章. Sonar 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- “全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java第三十五章:面向对象
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 第三十九章 POSIX信号量与互斥锁
POSIX信号量相关函数 sem_open 功能: initialize and open a named semaphore 原型: sem_t *sem_open(const char *name ...
- 【WPF学习】第三十五章 资源字典
如果希望在多个项目之间共享资源,可创建资源字典.资源字典只是XAML文档,除了存储希望使用的资源外,不做其他任何事情. 一.创建资源字典 下面是一个资源字典示例,它包含一个资源: <Resour ...
- 第三十五章 metrics(3)- codahale-metrics基本使用
<!-- metrics --> <dependency> <groupId>io.dropwizard.metrics</groupId> <a ...
- 【第三十五章】 metrics(3)- codahale-metrics基本使用
<!-- metrics --> <dependency> <groupId>io.dropwizard.metrics</groupId> <a ...
- SpringBoot | 第三十五章:Mybatis的集成和使用
前言 最近收到公众号留言说,单纯的Mybatis的集成和使用.前面在第九章:Mybatis-plus的集成和使用介绍了基于mybatis-plus的集成和使用.后者也只是对mybatis进行了功能增强 ...
- 第三十五章 Linux常规练习题(二)参考答案
一.练习题一 1.删除用户基本组shanghai03.发现无法正常删除,怎样才能将其删除掉,不能删除用户. groupdel shanghai03 移除其所属组的用户 2.打开多个xshell窗口连接 ...
随机推荐
- Spring Boot (八): Mybatis 增强工具 MyBatis-Plus
1. 简介 在上一篇文章<Spring Boot (七): Mybatis极简配置> 中我们介绍了在 Spring Boot 中 Mybatis 的基础使用方式,其中有一部分美中不足的是 ...
- 夯实Java基础系列16:一文读懂Java IO流和常见面试题
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- python语言程序设计基础(嵩天)第二章课后习题
p56: *2.1 实例1的修改.改造实例代码1.1,采用eval(input(<提示内容>))替换现有输入部分,并使输出的温度值为整数. 源代码: TempStr=input(" ...
- 求n以内的质数(质数的定义:在大于1的自然数中,除了1和它本身意外,无法被其他自然数整除的数)
思路: 1.(质数筛选定理)n不能够被不大于根号n的任何质数整除,则n是一个质数2.除了2的偶数都不是质数代码如下: /** * 求n内的质数 * @param int $n * @return ar ...
- Paid Roads POJ - 3411
A network of m roads connects N cities (numbered from 1 to N). There may be more than one road conne ...
- 虚拟机上安装centos8.0
一.准备宿主机 为了培训Hadoop生态的部署和调优技术,需要准备3台虚拟机部署Hadoop集群环境,能够保证HA,即主要服务没有单点故障,可执行基本功能,完成小内存模式的参数调整. 1.1.准备安装 ...
- wildfly(JBoss AS)应用服务器快速入门
什么是wildfly JBoss AS 从8版本起名为wildfly.Wildfly是一个开源的基于JavaEE的轻量级应用服务器.可以在任何商业应用中免费使用. WildFly是一个灵活的.轻量的. ...
- SLAM中的卡方分布
视觉slam中相邻帧特征点匹配时,动辄上千个特征点,匹配错误的是难免的,而误匹配势必会对位姿精度以及建图精度造成影响,那么如何分辨哪些是误匹配的点对儿呢?如果已知两帧的的单应矩阵,假设单应矩阵是没有误 ...
- Flask学习总结
Flask的使用以及返回值(其中Response后续详细单独补充) Flask的路由解读以及其配置 Flask的请求扩展 Flask中的cookie和session Flask中的request和re ...
- 二、docker 镜像容器常用操作(让我们用docker 溜得飞起)
前言 上篇讲了我们如何安装docker,现在该我们一展拳脚的时候了.接下来让我们一起学习一下docker常见的操作,让我们能够会使用 docker. 基本概念 在讲使用之前,还是先将一下docker ...