目录

简述

代码

写端代码

读取端代码

编译

运行


简述

共享内存是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

运行

最新文章

  1. CentOS 7.x设置自定义开机启动,添加自定义系统服务
  2. 【代码笔记】iOS-根据size截取屏幕中间矩形区域
  3. BIOS开启虚拟化
  4. 使用Eclipse将Web项目打Jar包方法
  5. php课程---JavaScript与Jquery的区别(转)
  6. 运行时报错-Verify the Developer App certificate for youraccount is trusted on your device. Open Settings on Mayoyi_sakura and navigate to General -&gt; Device Management, then select your
  7. Android中获取蓝牙log
  8. NetworkComms网络通信框架V3结构图
  9. 文件操作I
  10. windos系统快捷键 2015-05-08 23:31 24人阅读 评论(0) 收藏
  11. pch文件出现no such file or directory错误
  12. html&amp;&amp;css 基础知识笔记
  13. javascript 作用域链及闭包,AO,VO,执行环境
  14. 20175204 张湲祯 2018-2019-2《Java程序设计》第九周学习总结
  15. SQL Server中几种遍历方式比较
  16. MySQL数据库下载安装和DataGrip的下载安装和破解
  17. oracle sequence
  18. 月饼问题PAT B1020(贪心算法)
  19. 查看PHP代码执行的时间
  20. SQL Server 查询表的主键的两种方式

热门文章

  1. Show information of directory or disk
  2. Linux如何用脚本监控Oracle发送警告日志ORA-报错发送邮件
  3. Apache Hudi重磅特性解读之存量表高效迁移机制
  4. nginx反向代理导致session失效的问题处理
  5. Python Hacking Tools - Web Scraper
  6. “git pull” 强制覆盖本地文件
  7. 推特(Twitter)如何绑定谷歌二次验证码/谷歌身份验证/双重认证?
  8. .net core 发布程序命令(自带运行环境)
  9. SQL之DDL、DML、DCL、TCL
  10. w10查看wifi密码