Linux c 基于内存的进程通信—共享内存、共享队列(消息队列)
基于内存的进程通信:
1. 内核共享内存
编程模型:
1.1.创建共享内存,得到一个ID shmget
1.2.把ID影射成虚拟地址(挂载) shmat
1.3.使用虚拟地址访问内核共享内存使用任何内存函数与运算符号 1.4.卸载虚拟地址 shmdt
1.5.删除共享内存 shctl(修改/获取共享内存的属性)
案例:
A.创建共享内存,并且修改内存数据
1. 创建共享内存
#include<sys/shm.h>
intshmget(key_t key,//为什么需要key
int size,//共享内存大小
int flags//共享内存的属性与权限
)
为什么要key_t:
约定创建与访问的是同一个共享内存。Key为两个进程之间访问同一块共享内存的约定
注:key需要唯一性,因为我们不能保证我们自己定义的key的唯一性,所以为了保证kay的唯一性,我们需要用某个文件对应的整数来充当kay值,可以用ftok函数来将一个文件转化为一个kay值。(一般我们用两个进程的共同的工程目录文件来确定kay值)
ftok函数:
#include<sys/ipc.h>
key_t ftok( const char * pathname,int proj_id);
参数二:一个控制因子。建议在0—255之间
第三个参数:
方式|权限
方式:创建 IPC_CREAT IPC_EXCL(如果内存已经创建,直接错误返回)
打开:0
常见的两种方式:
创建:IPC_CREAT|IPC_EXCL | 0666;
打开:0
返回:
成功返回共享内存ID
失败返回-1
失败返回-1
B.根据ID得到共享内存,并且访问内存数据。
挂载共享内存
void* shmat(int id,
void*startaddr,//0:系统指定首地址
intflags)//挂载方式,建议0默认读写,可以使用IPC_RDONLY
返回值:合法地址成功,-1失败
C.删除
intshmctl(int id,//被操作的共享内存ID
inthow,//操作方式:一共三种操作
structshmid_ds*ds)//共享内存属性
how:
IPC_STAT
IPC_SET //修改属性
IPC_RMID //删除 参数三无用
案例代码:
ShmA.c
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/shm.h>
#include<sys/ipc.h>
void main()
{
key_t key;
int shmid;
int * p;
//1.创建共享内存
key=ftok( “.” , 255 ); //用当前路径的目录来确定kay值
if(key == -1) printf(“ftok error%m\n”) , exit( - 1 );
shmid=shmget( key , 4 , IPC_CREAT|IPC_EXCL | 0666 );
if(shmid == -1) printf(“shmget error %m\n”) , exit( -1 );
//2.挂载共享内存
p=shmat( shmid , 0 , 0);
if(p==(int *) - 1) printf(“at error %m\n”) , exit( -1 );
//3.访问共享内存
*p=999;
//4.卸载共享内存
shmdt(shmid);
//删除共享内存
shctl( shmid , IPC_RMID , 0);
}
不创建共享内存,只访问已有的
shmB.c
ShmA.c
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/shm.h>
#include<sys/ipc.h>
void main()
{
key_t key;
int shmid;
int * p;
//1.得到共享内存
key=ftok( “.” , 255 ); //用当前路径的目录来确定kay值
if(key == -1) printf(“ftok error%m\n”) , exit( - 1 );
shmid=shmget( key , 4 ,0 );
if(shmid == -1) printf(“shmget error %m\n”) , exit( -1 );
//2.挂载共享内存
p=shmat( shmid , 0 , 0);
if(p==(int *) - 1) printf(“at error %m\n”) , exit( -1 );
//3.访问共享内存
printf(“%d\n”,*p);
//4.卸载共享内存
shmdt(shmid);
}
2. 内核共享队列(有序)
编程模型:
2.1.创建共享队列/得到队列msgget
2.2.使用队列(发送消息msgsnd/接收消息msgrcv)
2.3.删除队列msgctl
案例:
创建共享队列
#include<sys/msg.h>
intmsgget(key_t,int); 除了不用指定大小,和shmget函数的参数一样
发送消息
intmsgsnd(
intid,//消息队列ID
constvoid *msg,//要发送消息
size_tlen,//消息的长度
int flags//发送消息的方式,建议为0
);
返回:
-1:失败
0:成功
第二个参数的消息有固定的格式
4字节:表示消息的类型
若干字节:消息内容。
消息格式:(该结构体需要我们自己定义)
struct msgbuf{
long mtype; //消息类型
char mtext[1]; //消息内容
}
第三个参数:
消息的大小,不包含类型的4个字节
接收消息:
size_t msgrcv(int id ,
void * msgp ,
size_t msgsz, ,
long msgtype , //那种类型的消息
int msgflg);
返回:
-1:失败
大小:成功
删除队列:msgctl 参数和shctl一样
案例代码:
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct msgbuf
{
long type;
char data[32];
}
void main()
{
key_t key;
int msgid;
//1创建消息队列
key= ftok(“ . ” , 254);
if(key == -1) printf(“ftok error:%m\n”) , exit(-1);
msgid= msgget(key,IPC_CREAT | IPC_EXCL|0666);
if(msgid==-1) printf(“get error : %m\n”), exit(-1);
//2构造消息
struct msgbuf msg;
//3发送消息
for(i=1;i<=10;i++)
{
msg.type=1; //消息类型自己定义一个long类型
sprintf(msg.data , “Message:%d”,i);
msgsnd(msgid ,&msg , strlen(msg.data) , 0);
}
//4删除队列
//msgctl(msgid, IPC_RMID,0);
}
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct msgbuf
{
long type;
char data[32];
}
void main()
{
key_t key;
int msgid;
//1得到消息队列
key = ftok(“ . ” , 254);
if(key == -1) printf(“ftok error:%m\n”) , exit(-1);
msgid= msgget(key,0);
if(msgid== -1) printf(“get error : %m\n”), exit(-1);
//2构造消息
struct msgbuf msg;
//3接收消息
while(1)
{
bzero(&msg,sizeof(msg));
msgrcv(msgid , & msg sizeof(msg.data) , 1 , 0);
printf(“%s\n”,msg.data);
}
}
说明:如果消息队列中没有消息了读取消息的程序会阻塞等待
当程序发送消息到队列中,一个程序读取了所以消息,队列中就没有消息,就无法再读取了,只能等待在发送消息后在读取消息。
转载于:https://www.cnblogs.com/bbsno1/p/3260627.html
Linux c 基于内存的进程通信—共享内存、共享队列(消息队列)相关推荐
- 删除共享内存_进程通信专题之 共享内存
什么是共享内存呢? 共享内存是被多个进程共享一部分物理内存,共享内存是进程间共享数据最快的办法,因为一个进程向共享内存中写了数据,那么共享的这个区域的所有进程就可以立刻看到这里的数据. 共享内存有什么 ...
- 进程通信学习笔记(System V消息队列)
跟Posix消息队列一样,不存在这样的要求:某个进程往一个队列中写入一个消息,另外一个进程下在等待该队列上一个消息的到达 系统中的消息队列,定义在<sys/msg.h>头文件中的信息结构: ...
- Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存
Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:<linux编程从入门到精通>,<Linux C程序设计大全>,<unix环境高级编程> ...
- java共享内存_Java进程通信之映像文件共享内存
Java进程通信之映像文件共享内存 1. 共享内存 vs 进程通信 对UNIX系统来说,共享内存分为一般共享内存和映像文件共享内存两种.但windows实际上只有影像文件共享内存一种. 而说到进程通信 ...
- linux ps内存占用率,linux ps命令,查看某进程cpu和内存占用率情况, linux ps命令,查看进程cpu和内存占用率排序。 不指定...
背景:有时需要单看某个进程的CPU及占用情况,有时需要看整体进程的一个占用情况. 一. linux ps命令,查看某进程cpu和内存占用率情况 [root@test vhost]# ps aux US ...
- linux使用共享内存进行进程通信
一.什么是共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常为同一段物理内存.使用共享内存进 ...
- python slice是共享内存吗_python共享内存实现进程通信
1.概述 共享内存可以说是最有用的进程间通信方式.两个不同的进程共享内存的意思是:同一块物理内存被映射到两个进程的各自的进程地址空间.一个进程可以及时看到另一个进程对共享内存的更新,反之亦然.采用共享 ...
- 操作系统实验·Linux进程通信与内存管理
预备知识 Linux进程的数据结构 在Linux中,进程用task_struct表示,所有进程被组织到以init_task为表头的双向链表中(见[include/linux/sched.h]SET_L ...
- Linux 内核、进程调度、进程通信、多线程、协程
Linux内核 操作系统是什么 内核是什么 从功能层面上来说,内核就是一个中间层,软件和硬件之间交互的中间层,链接层 从其他方面理解内核 系统调用,开放了很多接口:资源管理 内核实现的策略 宏内核 微 ...
最新文章
- SQL基本语法和书写格式
- 巨头纷纷看上的中国Robobus又获1亿美元投资
- python学习手册条件-Python学习手册(第4版)pdf
- 前端- jquery- 总结
- poi读取Excel内容数据
- ---Mybatis3学习笔记(2)
- java io删除文件_java IO 文件操作方法总结
- CS中using的使用-以FileStream写入文件为例
- android内容显示不出来,android – listview不显示任何内容并隐藏数据
- Spark Java API:broadcast、accumulator
- 解密双十一小程序云背后毫秒级伸缩的Serverless计算平台:函数计算
- thinkphp仿素材火教程_国外都用古风效果图获奖了,为什么你连素材都没有?
- centos oracle创建库,CentOS Oracle安装必要的软件创建数据库
- 苹果css攻击,研究人员设计了一种新的CSS和HTML攻击 导致iPhone重启或冻结Mac
- JS一些概念知识及参考链接
- Error mounting /dev/sdc1 at /media/XXXX: Command-line `mount -t “ntfs“ -o
- 声明 styleable 与声明 attr 的区别
- 利用Python进行百度文库内容爬取(一)
- 微PE系统安装包下载及安装教程,纯净微pe系统安装
- 【Linux环境下C语言编程】