目录

简述

代码

写端代码

读取端代码

编译

运行


简述

共享内存是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. python进阶之内置方法

    python进阶之内置方法 字符串类型的内置方法 常用操作与方法: 按索引取值 str[index] 切片 ste[start:stop:step] 长度 len(str) 成员运算in和not in ...

  2. java IO流 (五) 转换流的使用 以及编码集

    转换流的使用 1.转换流涉及到的类:属于字符流InputStreamReader:将一个字节的输入流转换为字符的输入流解码:字节.字节数组 --->字符数组.字符串 OutputStreamWr ...

  3. hihoCoder 1062 最近公共祖先·一 最详细的解题报告

    题目来源:最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 题目描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其 ...

  4. day1 python计算器底层运作,注释及变量

    每日一记 utf-8 国际标准编码(可变长的unicode编码)中文3字节,英文数字特殊字符1字节 gbk 中国标准编码 中文2字节,英文数字特殊字符1字节 1.原码,反码,补码 "&quo ...

  5. ffmpeg源码编译环境搭建

    ffmpeg是视频开发最常用到的开源软件,FFmpeg功能强大,用途广泛,提供几乎所有你能够想到的与视频开发相关的操作,许多商业软件都以ffmpeg为基础进行开发定制. FFmpeg: FFmpeg ...

  6. python 复制以及更改列表操作

    题目:设置一个老用户列表和一个新用户列表,检查老用户列表中是否与新注册的用户名字有重复(不区分大小写),老用户列表不能被破坏 usernames = ['admin','Tom','john','ja ...

  7. LGTB 与 序列

    题目描述 LGTB 有一个长度为 N 的序列 A ,现在他想构造一个新的长度为 N 的序列 B ,使得 B 中的任意两个数都互质.并且他要使 \sum_{1\le i\le N}|A_i-B_i| 最 ...

  8. SpringBoot2.x入门:使用MyBatis

    这是公众号<Throwable文摘>发布的第25篇原创文章,收录于专辑<SpringBoot2.x入门>. 前提 这篇文章是<SpringBoot2.x入门>专辑的 ...

  9. PyQt5基础控件

    QLabel标签 功能:在界面上显示文字.图片.链接等 接口: 方法 描述 setText() 设置显示的内容 setAlignment() 设置文字对齐方式 setToolTip() 设置提示信息 ...

  10. Java中的大数值使用

    在Java中,偶尔会遇到超大数值,超出了已有的int,double,float等等你已知的整数.浮点数范围,那么可以使用java.math包中的两个类:BigInteger和BigDecimal. 这 ...