共享内存区是最快的IPC(进程间通信)形式。
共享内存基本API:
#include<sys/ipc.h>
#include<sys/shm.h>
1. int shmget(key_t key,size_t size,int shmflg);
功能:用来创建共享内存
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将共享内存段连接到进程地址空间
3, int shmdt(const void *shmaddr);
功能:将共享内存段与当前进程脱离,但并不等于删除共享内存段
4, int shmctl(int shmid,int cmd,struct shmid_ds *buf);
功能:用于控制共享内存
cmd:将要采取的动作
(1)IPC_STAT 把shmid_ds结构中的数据设置为共享内存的当前关联值
(2)IPC_SET 在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值
(3)IPC_RMID 删除共享内存段
代码实现:
发送/写入端:shmwrite.c
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
int shmId;
char *shmaddr;
key_t key;
key = ftok(".",1); //为共享内存生成IPC键值
//int shmget(key_t key, size_t size, int shmflg); //创建一个共享内存
//返回值:成功返回共享内存id号,失败返回 -1;
//key: IPC键值
//shmflag: 共享内存的创建方式和权限
shmId = shmget(key,1024*3,IPC_CREAT | 0666); //IPC_CREAT,不管是否已存在该块共享内存,
//则都返回该共享内存的ID,
//若不存在则创建共享内存
//0666表示所以用户可读可写权限
if(shmId == -1){
printf("create shm fail\n");
exit(-1);
} //判断是否创建成功,成功继续失败退出
//void *shmat(int shmid, const void *shmaddr, int shmflg); //将共享内存挂载到此程序,使此程序可访问共享内存
//返回值:共享内存挂载到内存的地址
//key: IPC键值
//shmaddr:为挂载共享内存开辟空间
//shmflag: 共享内存的权限
shmaddr = shmat(shmId,0,0); //const void *shmaddr:为0表示linux内核自动分配
//int shmflg:此处为0表示权限默认为可读可写
printf("shmat ok\n");
strcpy(shmaddr,"fangXiaoChuan shaui"); //将"fangXiaoChuan shaui"拷贝进共享内存
sleep(5);//延时5 s等待其他程序或设备读走数据
//int shmdt(const void *shmaddr); //卸载共享内存,使程序无法访问共享内存
shmdt(shmaddr);
//int shmctl(int shmid, int cmd, struct shmid_ds *buf); //将共享内存移除
//int cmd: 告诉shmct1函数需要完成什么功能
//IPC_SET :设置共享内存属性信息(设置的时候为输入型参数)
//IPC_STAT :获取共享丙存属性信息(获取的时候为输出型参数)
//IPC_ RMID :删除共享内存,第三个参数传递NULL
//struct shmid_ds *buf: 用于保存共享内存的数据
shmctl(shmId,IPC_RMID,0); //struct shmid_ds *buf为0时表示不保存数据
printf("quit\n");
return 0;
}
接收/阅读端:shmread.c
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
int shmId;
char *shmaddr;
key_t key;
key = ftok(".",1);
//int shmget(key_t key, size_t size, int shmflg);
shmId = shmget(key,1024*3,0);
if(shmId == -1){
printf("create shm fail\n");
exit(-1);
}
//void *shmat(int shmid, const void *shmaddr, int shmflg);
shmaddr = shmat(shmId,0,0);
printf("shmat ok\n");
printf("data: %s\n",shmaddr);
//int shmdt(const void *shmaddr);
shmdt(shmaddr);
return 0;
}
运行注意事项:
(1)因为两个程序需要一起跑,所以最好开两个终端,并且最好起别名
开终端快捷键 Ctrl+Shift+N
编译时起别名:例如 :gcc shmwrite.c -o shmwrite
-o表示编译shmwrite.c时给生成的文件命名为shmwrite
例如 :gcc shmread.c -o shmread
(2)因为接收端未做共享内存的开辟,所以要先跑发送端
第一个终端运行: ./shmwrite
第二个终端运行:./shmread