第二十九章 System V共享内存
共享内存数据结构
共享内存函数
shmget
int shmget(key_t key, size_t size, int shmflg);
功能:
用于创建共享内存
参数:
key : 这个共享内存段名字
size : 共享内存大小
shmflg : 由9个权限位标志构成,它们的用法与创建文件时使用的mode模式标志是一样的
返回值:
成功 : 返回一个非负整数,即该共享内存段的标识码
失败 : -1
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct str
{
char name[32];
int age;
}STU;
int main(int argc, char* argv[])
{
int shmid;
shmid = shmget(1234, sizeof(STU), IPC_CREAT|0666);
if(shmid == -1)
ERR_EXIT("shmget");
return 0;
}
结果
ipcs
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
0x000004d2 9011220 dw 666 36 0
shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
将共享内存段连接到进程地址空间
参数:
shmid : 共享内存标识
shmaddr : 指定连接的地址
NULL : 核心自动选择一个地址
not NULL && 未设置SHM_RND标记,则以shmaddr为连接地址
not NULL && 设置了SHM_RND标记,则连接的地址会自动往下调整为SHMLBA的整数倍。公式 : shmaddr - (shmaddr % SHMLBA)
shmflg :
SHM_RND
SHM_RDONLY : 表示连接操作用来只读共享内存
返回值:
成功 : 返回一个指针,指向共享内存第一节
失败 : -1
shmdt
int shmdt(const void *shmaddr)
功能:
将共享内存段与当前进程脱离
参数:
shmaddr : 由shmat所返回的指针
返回值:
成功 : 0
失败 : -1
注意:
将共享内存段与当前进程脱离不等于删除共享内存段
shmget_write.c
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct str
{
char name[32];
int age;
}STU;
int main(int argc, char* argv[])
{
int shmid;
shmid = shmget(1234, sizeof(STU), IPC_CREAT|0666);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
//自动分配地址且可读可写
p = shmat( shmid, NULL, 0);
if(p == (void*)-1)
ERR_EXIT("shmat");
strcpy(p->name, "xiaoming");
p->age = 20;
sleep(10);
shmdt(p);
return 0;
}
结果
进程退出前
ipcs
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
0x000004d2 9011220 dw 666 36 1
进程退出后
ipcs
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
0x000004d2 9011220 dw 666 36 0
shmget_read.c
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct str
{
char name[32];
int age;
}STU;
int main(int argc, char* argv[])
{
int shmid;
//第二个参数,如果不知道大小可以填0
// shmid = shmget(1234, sizeof(STU), IPC_CREAT|0666);
shmid = shmget(1234, 0, 0);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
//自动分配地址且可读可写
p = shmat( shmid, NULL, 0);
if(p == (void*)-1)
ERR_EXIT("shmat");
printf("name : %s age : %d \n",p->name, p->age);
shmdt(p);
return 0;
}
shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:
用来控制共享内存
参数:
shmid : 共享内存标识
cmd : 要采取的操作
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段
buf : 是一个结构指针,它指向共享内存模式和访问权限的结构
返回值:
成功 : 0
失败 : -1
共享内存示例
shmget_write.c
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct str
{
char name[32];
int age;
}STU;
int main(int argc, char* argv[])
{
int shmid;
shmid = shmget(1234, sizeof(STU), IPC_CREAT|0666);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
//自动分配地址且可读可写
p = shmat( shmid, NULL, 0);
if(p == (void*)-1)
ERR_EXIT("shmat");
strcpy(p->name, "xiaoming");
p->age = 20;
while(1)
{
if(memcmp(p, "quit", 4) == 0)
break;
}
shmdt(p);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
shmget_read.c
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
typedef struct str
{
char name[32];
int age;
}STU;
int main(int argc, char* argv[])
{
int shmid;
//第二个参数,如果不知道大小可以填0
// shmid = shmget(1234, sizeof(STU), IPC_CREAT|0666);
shmid = shmget(1234, 0, 0);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
//自动分配地址且可读可写
p = shmat( shmid, NULL, 0);
if(p == (void*)-1)
ERR_EXIT("shmat");
printf("name : %s age : %d \n",p->name, p->age);
memcpy(p, "quit", 4);
shmdt(p);
return 0;
}
第二十九章 System V共享内存的更多相关文章
- 第二十五章 system v消息队列(一)
IPC对象的持续性 随进程持续 :一直存在直到打开的最后一个进程结束.(如pipe和FIFO) 随内核持续 :一直存在直到内核自举(内核自举就是把主引导记录加载到内存,并跳转执行这段内存)或显示删除( ...
- 第三十三章 System V共享内存与信号量综合
用信号量解决生产者.消费者问题 实现shmfifo ip.h #ifndef _IPC_H #define _IPC_H #include <unistd.h> #include < ...
- 第二十六章 system v消息队列(二)
msgsnd int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 作用: 把一条消息添加到消息队列中 参数: msqi ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- Linux system v 共享内存
system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...
- linux网络编程之system v共享内存
接着上次的共享内存继续学习,这次主要是学习system v共享内存的使用,下面继续: 跟消息队列一样,共享内存也是有自己的数据结构的,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 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
随机推荐
- nslookup的基本使用
nslookup的基本使用 nslookup:name server lookup 用来查询DNS的. 1:安装nslookup命令 [root@localhost ~]# yum install b ...
- ELK系列(二):.net core中使用ELK
ELK安装好后,我们现在.net Core中使用一下,大体思路就是结合NLog日志组件将数据写入ELK中,其它语言同理. ELK的安装还是有些复杂的,我们也可以在Docker中安装ELK:docker ...
- yzoj P2371 爬山 题解
背景 其实 Kano 曾经到过由乃⼭,当然这名字⼀看⼭主就是 Yuno 嘛.当年 Kano 看见了由乃⼭,内⼼突然涌出了⼀股杜甫会当凌绝顶,⼀览众⼭⼩的 豪⽓,于是毅然决定登⼭.但是 Kano 总是习 ...
- Python celery和Redis入门安装使用(排难帖)
1.redis安装 下载地址 https://github.com/MicrosoftArchive/redis/releases,选择Redis-x64-3.2.100.msi5.8 MB下载就好了 ...
- python爬虫—— 抓取今日头条的街拍的妹子图
AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 近期在学习获取j ...
- MongoDB 学习笔记之 分析器和explain
MongoDB分析器: 检测MongoDB分析器是否打开: db.getProfilingLevel() 0表示没有打开 1表示打开了,并且如果查询的执行时间超过了第二个参数毫秒(ms)为单位的最大查 ...
- Android_基于监听的事件处理机制
一.引言 在经过几天的学习之后, 首先熟悉了几大基本布局以及一些常用控件的使用方法,目前正在学习如何实现一个基本的登录注册界面及其功能,而实现功能就需要我们采用事件处理机制来进行调用事件处理方法.以下 ...
- 关于IDEA的Maven打jar包springboot项目问题,打成可执行jar包,IDEA创建的maven项目和spring initializr项目
Spring Initializr创建的项目 源文件地址 https://github.com/TaoPanfeng/maven-package 项目的创建步骤 进行打包 clear package ...
- smp_processor_id()获取当前执行cpu_id
基于Linux 2.6.32内核进行分析,看本篇文章前,建议先看看percpu变量这篇文章 smp_processor_id()用来获取当前cpu的id,首先来看smp_processor_id的定义 ...
- tp5中使用中间控制器代理路由,以避免创建过多的无用控制器方法
在写项目的时候偶尔会加载一些不需要传递参数的静态视图,例如 class Index extends Common { public function index() { return $this-&g ...