Linux进程间通信之《共享内存》入门
2024-09-24 12:58:58
目录
简述
共享内存是Linux系统进程间通信常用的方式,通常用于数据量较大的情况,如果只是用于不同的进程间消息通知,那不如用消息队列或者socket。之前做的项目中,使用共享内存的其实只有一种情况:视频数据的共享。设备类似于DVR,视频采集编码在一个独立的程序中,另一个程序负责协议通信。
共享内存要想好用,共享的那段内存,需要用数据结构和队列组织起来,加上读写索引和数据有效标志(已读和未读、可读)。下面的这个示例代码是我初学时的,适合入门和了解使用流程。
代码
写端代码
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#define N 1024
typedef struct
{
pid_t pid;
char text[N];
}SHMBUF;
void handler(int signo) {printf("signo=%d\n", signo);}
int main()
{
int shmid;
SHMBUF *shmadd;
key_t key;
pid_t peerpid;
if ((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(-1);
}
signal(SIGUSR1, handler);
if ((shmid = shmget(key, sizeof(SHMBUF), 0666 | IPC_CREAT | IPC_EXCL)) == -1)
{
if (errno == EEXIST)
{
shmid = shmget(key, sizeof(SHMBUF), 0666);
if ((shmadd = (SHMBUF *)shmat(shmid, NULL, 0)) == (SHMBUF *)-1)
{
perror("shmat");
exit(-1);
}
peerpid = shmadd->pid;
shmadd->pid = getpid();
kill(peerpid, SIGUSR1);
}
else
{
perror("shmget");
exit(-1);
}
}
else //first process
{
if ((shmadd = (SHMBUF *)shmat(shmid, NULL, 0)) == (SHMBUF *)-1)
{
perror("shmat");
exit(-1);
}
shmadd->pid = getpid();
//sprintf(shmadd, "%d", getpid());
pause();
peerpid = shmadd->pid;
}
printf(">");
while (1)
{
fgets(shmadd->text, N, stdin);
shmadd->text[strlen(shmadd->text)-1] = '\0';
kill(peerpid, SIGUSR1);
if (strncmp(shmadd->text, "quit", 4) == 0)
{
sleep(1);
if (shmdt(shmadd) == -1)
{
perror("shmdt");
}
if (shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("RM");
exit(-1);
}
exit(0);
}
pause();
printf(">");
}
return 0;
}
读取端代码
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#define N 1024
typedef struct
{
pid_t pid;
char text[N];
}SHMBUF;
void handler(int signo) {printf("signo=%d\n", signo);}
int main()
{
int shmid;
SHMBUF *shmadd;
key_t key;
pid_t peerpid;
if ((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(-1);
}
signal(SIGUSR1, handler);
if ((shmid = shmget(key, sizeof(SHMBUF), 0666 | IPC_CREAT | IPC_EXCL)) == -1)
{
if (errno == EEXIST)
{
shmid = shmget(key, sizeof(SHMBUF), 0666);
if ((shmadd = (SHMBUF *)shmat(shmid, NULL, 0)) == (SHMBUF *)-1)
{
perror("shmat");
exit(-1);
}
peerpid = shmadd->pid;
shmadd->pid = getpid();
kill(peerpid, SIGUSR1);
}
else
{
perror("shmget");
exit(-1);
}
}
else //first process
{
if ((shmadd = (SHMBUF *)shmat(shmid, NULL, 0)) == (SHMBUF *)-1)
{
perror("shmat");
exit(-1);
}
shmadd->pid = getpid();
pause();
peerpid = shmadd->pid;
}
while (1)
{
pause();
printf("read %s\n", shmadd->text);
if (strncmp(shmadd->text, "quit", 4) == 0)
{
if (shmdt(shmadd) == -1)
{
perror("shmdt");
}
exit(0);
}
// sleep(1);
usleep(100000);
kill(peerpid, SIGUSR1);
}
exit(0);
}
编译
gcc reader.c -o reader
gcc writer.c -o writer
运行
最新文章
- CentOS 7.x设置自定义开机启动,添加自定义系统服务
- 【代码笔记】iOS-根据size截取屏幕中间矩形区域
- BIOS开启虚拟化
- 使用Eclipse将Web项目打Jar包方法
- php课程---JavaScript与Jquery的区别(转)
- 运行时报错-Verify the Developer App certificate for youraccount is trusted on your device. Open Settings on Mayoyi_sakura and navigate to General ->; Device Management, then select your
- Android中获取蓝牙log
- NetworkComms网络通信框架V3结构图
- 文件操作I
- windos系统快捷键 2015-05-08 23:31 24人阅读 评论(0) 收藏
- pch文件出现no such file or directory错误
- html&;&;css 基础知识笔记
- javascript 作用域链及闭包,AO,VO,执行环境
- 20175204 张湲祯 2018-2019-2《Java程序设计》第九周学习总结
- SQL Server中几种遍历方式比较
- MySQL数据库下载安装和DataGrip的下载安装和破解
- oracle sequence
- 月饼问题PAT B1020(贪心算法)
- 查看PHP代码执行的时间
- SQL Server 查询表的主键的两种方式
热门文章
- Show information of directory or disk
- Linux如何用脚本监控Oracle发送警告日志ORA-报错发送邮件
- Apache Hudi重磅特性解读之存量表高效迁移机制
- nginx反向代理导致session失效的问题处理
- Python Hacking Tools - Web Scraper
- “git pull” 强制覆盖本地文件
- 推特(Twitter)如何绑定谷歌二次验证码/谷歌身份验证/双重认证?
- .net core 发布程序命令(自带运行环境)
- SQL之DDL、DML、DCL、TCL
- w10查看wifi密码