目录

简述

代码

写端代码

读取端代码

编译

运行


简述

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

运行

Linux进程间通信之《共享内存》入门的更多相关文章

  1. Linux进程间通信—使用共享内存

    Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...

  2. Linux进程间通信——使用共享内存

    一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...

  3. linux进程间通信之共享内存篇

    本文是对http://www.cnblogs.com/andtt/articles/2136279.html中共享内存(上)的进一步阐释说说明 1 共享内存的实现原理 共享内存是linux进程间通讯的 ...

  4. Linux进程间通信——使用共享内存(转)

    一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...

  5. Linux进程间通信(四) - 共享内存

    共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...

  6. linux进程间通信之共享内存学习记录

    进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed). 广义定义:进程是一个具有一定独立功能的 ...

  7. Linux进程间通信之共享内存

    一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...

  8. linux进程间通信同步-共享内存

    参考:https://www.cnblogs.com/charlesblc/p/6142868.html 使用有名信号量,sem_open().sem_close().sem_post().sem_w ...

  9. 浅析Linux下进程间通信:共享内存

    浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...

  10. Linux环境进程间通信(五): 共享内存(下)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

随机推荐

  1. Typora上传图片设置

    Typora上传图片设置 问题 使用Typora写文档时上传图片的路径默认是本地磁盘的路径,这样就导致一个问题,当写好的文档上传到blog.csdn等博客网站时,会导致图片失效无法识别的问题. 解决方 ...

  2. MYSQL 之 JDBC(三): 增删改查(一)通过Statement执行更新操作

    Statement测试 /** * 通过JDBC向指定的数据表中插入一条记录 * 1. Statement:用于执行sql语句的对象 * 1.1 通过Connection的createStatemen ...

  3. 一张PDF了解JDK10 GC调优秘籍-附PDF下载

    目录 简介 Java参数类型 Large Pages JIT调优 总结 简介 今天我们讲讲JDK10中的JVM GC调优参数,JDK10中JVM的参数总共有1957个,其中正式的参数有658个. 其实 ...

  4. linux 安装 mysql8

    1. 下载地址: https://dev.mysql.com/downloads/file/?id=484922 2. 安装 mysql80-community-release-el7-3.noarc ...

  5. Captura - 免费好用还开源的录屏软件

    首先下载这个软件,国内下载很慢这里提供一个国内下载UCloud-OSS 软件打开后默认英文,现在我们切换到中午模式 在录制屏幕的同时获取声音

  6. C++语法小记---类型转换

    类型转换 C++类型转换主要包含两种: 隐式类型转换 小类型向大类型转换 char -> int short ->int int -> unsigned int int -> ...

  7. SQL数据多条转单条(CONCAT_WS)

    一.concat()函数可以连接一个或者多个字符串 concat(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. select conc ...

  8. jmeter零散知识点

  9. LaTeX公式学习

    简介 本文公式较多可能有加载较慢. 使用 LaTeX 的主要原因之一是它可以方便地排版公式.我们使用数学模式来排版公式. 公式 插入公式 可以用一对$来启用数学模式. 行中公式可以用如下方法: $数学 ...

  10. 记一次抓包和破解App接口

    目录 第一章 · 起源 第二章 · 尝试 第三章 · 脱狱 第四章 · 柳暗花明 第五章 · 终结 第一章 · 起源 某日,想做个爬虫工具,爬某个网站上的数据已做实验之用.大家都知道爬pc网页上的数据 ...