c/c++ linux 进程间通信系列4,使用共享内存
linux 进程间通信系列4,使用共享内存
1,创建共享内存,用到的函数shmget, shmat, shmdt
| 函数名 | 功能描述 |
|---|---|
| shmget | 创建共享内存,返回pic key |
| shmat | 第一次创建完共享内存时,它还不能被任何进程访问,shmat()函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间 |
| shmdt | 该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。 |
int shmget(key_t key, size_t size, int shmflg);
第一个参数,与信号量的semget函数一样,程序需要提供一个参数key(非0整数),它有效地为共享内存段命名,shmget()函数成功时返回一个与key相关的共享内存标识符(非负整数),用于后续的共享内存函数。调用失败返回-1.
不相关的进程可以通过该函数的返回值访问同一共享内存,它代表程序可能要使用的某个资源,程序对所有共享内存的访问都是间接的,程序先通过调用shmget()函数并提供一个键,再由系统生成一个相应的共享内存标识符(shmget()函数的返回值),只有shmget()函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。
第二个参数,size以字节为单位指定需要共享的内存容量
第三个参数,shmflg是权限标志,它的作用与open函数的mode参数一样,如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作。共享内存的权限标志与文件的读写权限一样,举例来说,0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共享内存。
void *shmat(int shm_id, const void *shm_addr, int shmflg);
- 第一个参数,shm_id是由shmget()函数返回的共享内存标识。
- 第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
- 第三个参数,shm_flg是一组标志位,通常为0。
调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.
2,访问共享内存
3,删除共享内存
int shmctl(int shm_id, int command, struct shmid_ds *buf);
- 第一个参数,shm_id是shmget()函数返回的共享内存标识符。
- 第二个参数,command是要采取的操作,它可以取下面的三个值 :
- PC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
- IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
- IPC_RMID:删除共享内存段
- 第三个参数,buf是一个结构指针,它指向共享内存模式和访问权限的结构。
1,创建共享内存,用到的函数shmget, shmat, shmdt
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
int main(){
int shm;
char* ptr;
shm = shmget(IPC_PRIVATE, 129, IPC_CREAT | 0600);
if(shm < 0){
perror("shmget");
return 1;
}
ptr = (char*)shmat(shm, NULL , 0);
if(atoi(ptr) == -1){
perror("shmat");
return -1;
}
strcpy(ptr, "HELLO");
shmdt(ptr);
return 0;
}
用下面的命令,能够查看到上面的程序创建的共享内存。
ipcs -m
2,访问共享内存
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
int shm;
char* ptr;
if(argc != 2){
return 1;
}
shm = atoi(argv[1]);
ptr = (char*)shmat(shm, NULL, 0);
if(atoi(ptr) == -1){
perror("shmat");
return 1;
}
printf("string from shared memory : %s\n", ptr);
shmdt(ptr);
return 0;
}
执行方法:【ipcs -m】执行后,得到下面的数字。
./a.out 789884
3,删除共享内存
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
int shm;
shmid_ds sds;
if(argc != 2){
printf("argc is wrong");
return 1;
}
shm = atoi(argv[1]);
if(shmctl(shm, IPC_RMID, &sds) != 0){
perror("shmctl");
return 1;
}
return 0;
}
用命令行删除共享内存:【ipcs -m】执行后,得到下面的数字。
ipcrm -m 321843
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ linux 进程间通信系列4,使用共享内存的更多相关文章
- c/c++ linux 进程间通信系列6,使用消息队列(message queue)
linux 进程间通信系列6,使用消息队列(message queue) 概念:消息排队,先进先出(FIFO),消息一旦出队,就从队列里消失了. 1,创建消息队列(message queue) 2,写 ...
- c/c++ linux 进程间通信系列5,使用信号量
linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...
- c/c++ linux 进程间通信系列7,使用pthread mutex
linux 进程间通信系列7,使用pthread mutex #include <stdio.h> #include <stdlib.h> #include <unist ...
- c/c++ linux 进程间通信系列3,使用socketpair,pipe
linux 进程间通信系列3,使用socketpair,pipe 1,使用socketpair,实现进程间通信,是双向的. 2,使用pipe,实现进程间通信 使用pipe关键点:fd[0]只能用于接收 ...
- c/c++ linux 进程间通信系列2,使用UNIX_SOCKET
linux 进程间通信系列2,使用UNIX_SOCKET 1,使用stream,实现进程间通信 2,使用DGRAM,实现进程间通信 关键点:使用一个临时的文件,进行信息的互传. s_un.sun_fa ...
- c/c++ linux 进程间通信系列1,使用signal,kill
linux 进程间通信系列1,使用signal,kill 信号基本概念: 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.进程之间可以互相通过系统调用kill发送软中断信号.内核 ...
- 【转】Linux环境进程间通信(五) 共享内存(上)
转自:https://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以 ...
- <转>Linux环境进程间通信(五): 共享内存(下)
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html 系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通 ...
- <转>Linux环境进程间通信(五): 共享内存(上)
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写 ...
随机推荐
- LeetCode算法题-Image Smoother(Java实现)
这是悦乐书的第282次更新,第299篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第150题(顺位题号是661).给定表示图像灰度的2D整数矩阵M,您需要设计一个平滑器以 ...
- vue框架中的Axios封装
function axios(options) { let promise = new Promise((resolve, reject) => { var xhr ...
- 快速搭建WebAPI(Odata+Code-First)附Odata条件查询表~
Odata是什么? 开放数据协议(Open Data Protocol,缩写OData)是一种描述如何创建和访问Restful服务的OASIS标准.该标准由微软发起,前三个版本1.0.2.0.3.0都 ...
- 使用Spring Cloud搭建高可用服务注册中心
我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客[使用Spring Cloud搭建服务注册中心]中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭 ...
- 如何比较版本号--Python实现
需求 在写一个程序Django项目的setup程序(初始化环境,比如设置PIP源,安装该项目依赖的各种模块等操作)遇到一个系统当前模块版本和项目所需版本的比较然后给出建议是忽略还是升级.我的要求是不仅 ...
- 如何发起、防御和测试XSS攻击,我们用DVWA来学习(上)
XSS 全称Cross Site Scripting 即‘跨站脚本攻击’. 从其中文释义我们能直观的知道,这是一种对网站的攻击方式. 其原理在于,使用一切可能手段,将可执行脚本(scripting)植 ...
- Chapter 4 Invitations——16
While I was sitting there, looking everywhere but at the car in front of me, I heard a knock on my p ...
- leetcode — scramble-string
import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/scramble-string/ * * Given ...
- Linux常用命令详解(week1_day1_3)--技术流ken
本节内容 pidofpstopipuptimewgetcurltrddtargrepfind 命令详解 1.pidof 获取正在运行程序的PID 实例1: [root@ken ~]# pidof ss ...
- C#线程同步--线程通信
问题抽象:当某个操作的执行必须依赖于另一个操作的完成时,需要有个机制来保证这种先后关系.线程通信方案:ManualResetEventSlim.ManualResetEvent.AutoResetEv ...