linux共享内存简单介绍以及编码演示
共享内存的基本概念
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
下图是共享内存示意图:
下图是用管道或者消息队列传递数据示意图:
内核为每个IPC对象维护一个数据结构
下图是用共享内存传递数据示意图:
System V共享内存API:
首先了解一下下面结构体
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 */
...
};
共享内存函数
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
下面依次介绍一下上述函数的一些使用方法
shmget函数
功能:用来创建共享内存
原型:intshmget(key_t key, size_t size, intshmflg);
参数:
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
shmat函数
功能:将共享内存段连接到进程地址空间
原型:void *shmat(intshmid, const void *shmaddr, intshmflg);
参数:
shmid: 共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
shmdt函数
功能:将共享内存段与当前进程脱离
原型:intshmdt(const void *shmaddr);
参数:
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数
功能:用于控制共享内存
原型:intshmctl(intshmid, intcmd, structshmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1
生成共享内存示例代码:
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h> typedef struct _Teacher
{
char name[];
int age;
}Teacher; int main(int argc, char *argv[])
{
int ret = ;
int shmid;
//创建共享内存 ,相当于打开文件,文件不存在则创建
shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT | );
if (shmid == -)
{
perror("shmget err");
return errno;
}
printf("shmid:%d \n", shmid);
Teacher *p = NULL;
//将共享内存段连接到进程地址空间
p = shmat(shmid, NULL, );//第二个参数shmaddr为NULL,核心自动选择一个地址
if (p == (void *)- )
{
perror("shmget err");
return errno;
}
strcpy(p->name, "aaaa");
p->age = ;
//将共享内存段与当前进程脱离
shmdt(p); printf("键入1 删除共享内存,其他不删除\n"); int num;
scanf("%d", &num);
if (num == )
{
//用于控制共享内存
ret = shmctl(shmid, IPC_RMID, NULL);//IPC_RMID为删除内存段
if (ret < )
{
perror("rmerrr\n");
}
} return ;
}
执行程序过程及测试步骤如下图:
获取共享内存示例代码:
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h> typedef struct _Teacher
{
char name[];
int age;
}Teacher; int main(int argc, char *argv[])
{
int ret = ;
int shmid;
//shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT |IPC_EXCL | 0666);
//打开获取共享内存
shmid = shmget(0x2234, , );
if (shmid == -)
{
perror("shmget err");
return errno;
}
printf("shmid:%d \n", shmid);
Teacher *p = NULL;
//将共享内存段连接到进程地址空间
p = shmat(shmid, NULL, );
if (p == (void *)- )
{
perror("shmget err");
return errno;
} printf("name:%s\n", p->name);
printf("age:%d \n", p->age);
//将共享内存段与当前进程脱离
shmdt(p); printf("键入1 程序暂停,其他退出\n"); int num;
scanf("%d", &num);
if (num == )
{
pause();
}
return ;
}
执行程序步骤以及演示结果:
linux共享内存简单介绍以及编码演示的更多相关文章
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
- Linux守护进程简单介绍和实例具体解释
Linux守护进程简单介绍和实例具体解释 简单介绍 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程. ...
- Linux curl使用简单介绍
在两台新搬迁的微信服务器上执行命令: curl -H "Content-Type: application/json" -d '{"partner_no":&q ...
- linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...
- linux 共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- Linux共享内存(一)
inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...
- linux 共享内存实现
说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享 ...
- Linux 共享内存编程
共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...
随机推荐
- Packet for query is too large (1166 > 1024). You can change this value
转载: MySQL max_allowed_packet 设置过小导致记录写入失败 mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_pack ...
- CodeForces 732B Cormen — The Best Friend Of a Man
B. Cormen - The Best Friend Of a Man time limit per test 1 second memory limit per test 256 megabyte ...
- 解决:R读取含中文excel文件,read.xlsx乱码问题
1.新建testexcel.xlsx文件 2.创建R文件:test.R # 定义文件变量 excel_path <- "chapter2/testexcel.xlsx" # ...
- 解决Cell重绘导致 重复的问题
IOS在Cell上的优化令人觉得底层框架的成熟,可是有些情形却会造成不必要的麻烦, 当使用了 UITableViewCell *cell = [tableView dequeueReusableCel ...
- 大文本 mysql es
大文本 mysql es mysql id longText ---> es longText mysqlId 大文本先入mysql,再同步至es: 文本查询逻辑交由es实现: mysq ...
- 解决mysql不能通过'/tmp/mysql.sock 连接的问题
解决方法:php标准配置正是通过'/tmp/mysql.sock',但一些mysql安装方法将mysql.sock放在/var/lib/mysql.sock或者其他地方,你可以通过修改/etc/my. ...
- react 日期
1.首先安装moment : npm install moment --save 2.在文件中引用: import moment from 'moment' 3.使用方式: 当前时间:moment() ...
- Amr and Chemistry---cf558C(暴力,加技巧)
题目链接:http://codeforces.com/problemset/problem/558/C 题意:有n个数,每个数都可以进行两个操作 *2 或者 /2,求最小的操作次数和,使得所有的数都相 ...
- 使用python的logging模块(转)
一.从一个使用场景开始 开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件 import logging # 创建一个logger logger = logging.getLogger(' ...
- python迟邦定
1.绑定 将函数体和函数调用关联起来,就叫绑定 2.迟绑定 在程序运行之前(也就是编译和链接时)执行的绑定是早绑定,迟绑定(late binding)是发生在运行时. 3.实例说明 def outer ...