C++ 进程间通信

2023-05-16

一,C++ 常用进程间通信

  • 管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
  • 命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
  • 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;Linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
  • 消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
  • 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
  • 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
  • 套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

二,共享内存

  1. 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。
  2. 因为多个进程可以同时操作,所以需要进行同步。

  3. 信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

// boosttest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <boost/lexical_cast.hpp>       
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>

using namespace std;
using namespace boost::interprocess;

int main(int argc,char *argv[])
{
	cout << "argc" << argc<<argv[0];
	if (argc == 1) {//父进程
		//1 删除共享内存
		struct  shm_remove
		{
			shm_remove() { shared_memory_object::remove("SharedMemory"); }
			~shm_remove() { shared_memory_object::remove("SharedMemory"); }
		}remover;


	//2 创建共享内存段
	shared_memory_object shm(create_only, "SharedMemory", read_write);

	//3 设置共享内存大小
	shm.truncate(100);

	//4 映射共享内存片段
	mapped_region region(shm, read_write);

	//5 初始化为1
	std::memset(region.get_address(), 1, region.get_size());
	
	//运行子进程
	std::string s(argv[0]);
	s += " child ";
	if (0 != std::system(s.c_str()))
		return 1;
	}
	else
	{
		//1 创建共享内存
		shared_memory_object shm(open_only, "SharedMemory", read_only);

		//2 映射共享内存
		mapped_region region(shm, read_only);

		//3 检查共享内存是否被初始化为1
		char* mem = static_cast<char*>(region.get_address());
		for (std::size_t i = 0; i < region.get_size(); ++i) {
			if (*mem++ != 1)
				return 1;
			else
			{
				printf("mem:%d   ", *mem);
			}
		}
	}

	system("pause");
	return 0;
}

三,消息队列

  1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

  2. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

// boosttest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <boost/lexical_cast.hpp>       
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <vector>

using namespace std;
using namespace boost::interprocess;

int main(int argc,char *argv[])
{
	cout << "argc" << argc<<argv[0];
	if (argc == 1) {//父进程
		//1 删除消息队列
		message_queue::remove("message_queue");

	//2 创建消息队列
		message_queue mq(create_only, "message_queue", 100, sizeof(int));

	//3 发送100个数字
		for (int i = 0; i < 100; ++i) {
			mq.send(&i, sizeof(i), 0);
	}
	
	//运行子进程
	std::string s(argv[0]);
	s += " child ";
	if (0 != std::system(s.c_str()))
		return 1;
	}
	else
	{
		//1 打开消息队列
		message_queue mq(open_only, "message_queue");

		unsigned int priority;
		message_queue::size_type recvd_size;
		for (int i = 0; i < 100; i++)
		{
			int number;
			mq.receive(&number, sizeof(number),recvd_size,priority);
			if (number != i || recvd_size != sizeof(number))
				return 1;
			else
				printf("number:%d ", number);
		}
		
		message_queue::remove("message_queue");
	}

	system("pause");
	return 0;
}

四,信号量

  1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。

  2. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

  3. 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

  4. 支持信号量组。

// boosttest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

// boosttest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <boost/lexical_cast.hpp>       
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>

using namespace std;
using namespace boost::interprocess;

struct  shared_memory_buffer
{
	enum { NumItems = 100};//数组大小
	shared_memory_buffer():mutex(1),nempty(NumItems),nstored(0){}

		interprocess_semaphore mutex, nempty, nstored;//匿名信号量
		int items[NumItems];//共享数组
};
int main(int argc, char *argv[])
{
	//cout << "argc" << argc << argv[0];
	if (argc == 1) {//父进程
		//1 删除共享内存
		struct  shm_remove
		{
			shm_remove() { shared_memory_object::remove("SharedMemory"); }
		}remover;


		//2 创建共享内存段
		shared_memory_object shm(create_only, "SharedMemory", read_write);

		//3 设置共享内存大小
		shm.truncate(sizeof(shared_memory_buffer));

		//4 映射共享内存片段
		mapped_region region(shm, read_write);

		//5 写数据,数据满了会阻塞
		void *addr = region.get_address();
		shared_memory_buffer *data = new(addr)shared_memory_buffer;
		const int NumMsg = 100;
		for (int i = 0; i < NumMsg; ++i) {
			data->nempty.wait();
			data->mutex.wait();
			data->items[i%shared_memory_buffer::NumItems] = i;
			data->mutex.post();
			data->nstored.post();
		}
	}
	else
	{
		struct shm_remove
		{
			~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
		} remover;

		//1 创建共享内存
		shared_memory_object shm(open_only, "SharedMemory", read_write);

		//2 映射共享内存
		mapped_region region(shm, read_write);

		//3 共享数据复制到自己的缓冲
		void * addr = region.get_address();
		shared_memory_buffer* data = static_cast<shared_memory_buffer*>(addr);
		const int NumMsg = 100;
		int extracted_data[NumMsg];

		for (int i = 0; i < NumMsg; ++i) {
			data->nstored.wait();
			data->mutex.wait();
			extracted_data[i] = data->items[i%shared_memory_buffer::NumItems];
			printf("data:%d ", data->items[i%shared_memory_buffer::NumItems]);
			data->mutex.post();
			data->nempty.post();
		}
	}

	system("pause");
	return 0;
}

信号量与互斥锁的区别:

1,作用域

信号量: 进程间或线程间(linux仅线程间)

互斥锁: 线程间

2,上锁时

信号量: 只要信号量的value大于0,其他线程就可以wait成功,成功后信号量的value减一。若value值不大于0,则wait阻塞,直到post释放后value值加一

互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源

 

参考:https://zhidao.baidu.com/question/1051708411830978339.html

https://www.cnblogs.com/ltm5180/p/4334522.html

http://blog.sina.com.cn/s/blog_a9cdad020102wy0e.html

https://blog.csdn.net/everysmile/article/details/50573668

https://www.cnblogs.com/zgq0/p/8780893.html

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 进程间通信 的相关文章

  • 【C++服务器入门基础------4.IPC进程间通信--管道】

    大学生寒假在家过于无聊 xff0c 整理一下以前学过的知识 xff0c 顺便复习一下 xff0c 水平较低 xff0c 专业性差 xff0c 仅供参考 xff0c 不喜勿喷 xff08 反正也没人看 xff09 连续一周多出去泡妞了 xff
  • 进程间通信

    原作者地址不详 摘 要 随着人们对应用程序的要求越来越高 xff0c 单进程应用在许多场合已不能满足人们的要求 编写多进程 多线程程序成为现代程序设计的一个重要特点 xff0c 在多进程程序设计中 xff0c 进程间的通信是不可避免的 Mi
  • c++进程间通信

    C 语言中的进程间通信方式有多种 xff0c 包括共享内存 消息队列 信号量 套接字等 共享内存是指多个进程可以访问同一块内存 xff0c 从而实现进程间的通信 共享内存的优点是速度快 xff0c 但实现较为复杂 xff0c 需要自己维护同
  • C++ 进程间通信

    一 xff0c C 43 43 常用进程间通信 管道 Pipe xff1a 管道可用于具有亲缘关系进程间的通信 xff0c 允许一个进程和另一个与它有共同祖先的进程之间进行通信 命名管道 named pipe xff1a 命名管道克服了管道
  • 【进程间通信】——认识同步与互斥,了解生产者消费者原理。

    临界资源 在操作系统中 xff0c 进程是占有资源的最小单位 xff08 线程可以访问其所在进程内的所有资源 xff0c 但线程本身并不占有资源或仅仅占有一点必须资源 xff09 但对于某些资源来说 xff0c 其在同一时间只能被一个进程所
  • Orange's 进程间通信

    新增一个系统进程 xff0c 和TESTA进行通信 xff0c 通信的流程是这样的 xff0c 如果首先执行到系统进程 xff0c 发送消息 xff0c 那么会触发内中断到ring0级 xff0c 完成发送所需要的动作 xff0c 之后回到
  • linux消息队列服务,Linux进程间通信-消息队列(mqueue)深入理解

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信 xff0c 本文将介绍Linux消息队列 posix 的通信机制和特点 1 消息队列 消息队列的实现分为两种 xff0c 一种为System V的消息队列 xff0c 一种是Posi
  • 第3讲 进程间通信

    文章目录 3 1 简介3 2 互联网协议的API3 3 外部数据表示和编码3 4 组播通信3 5 网络虚拟化 xff1a 覆盖网络 3 1 简介 UDP的应用程序接口提供了消息传递 xff08 Message Passing xff09 抽
  • Linux进程间通信

    1 unix域套接字 域套接字 xff1a 1 只能用于同一设备上不同进程之间的通信 xff1b 2 效率高于网络套接字 域套接字仅仅是复制数据 xff0c 并不走协议栈 xff1b 3 可靠 xff0c 全双工 xff1b 2 IP套接字
  • 漫谈QNX(架构/进程,线程,同步,进程间通信IPC)

    1 架构 说起Blackberry的QNX操作系统 想必大家都听说过 xff0c 但到底为什么QNX能如此有名 xff1f 难道微软的Windows和Linux都不能与之抗衡 xff1f 美国NASA的太空接驳飞船也使用QNX操作系统 QN
  • 进程间通信

    原作者地址不详 摘 要 随着人们对应用程序的要求越来越高 xff0c 单进程应用在许多场合已不能满足人们的要求 编写多进程 多线程程序成为现代程序设计的一个重要特点 xff0c 在多进程程序设计中 xff0c 进程间的通信是不可避免的 Mi
  • Orange's 进程间通信

    新增一个系统进程 xff0c 和TESTA进行通信 xff0c 通信的流程是这样的 xff0c 如果首先执行到系统进程 xff0c 发送消息 xff0c 那么会触发内中断到ring0级 xff0c 完成发送所需要的动作 xff0c 之后回到
  • linux---进程间通信(ipc)之管道

    进程间通信方式 管道共享内存消息队列信号量本地套接字等等都能作为我们进程间通信的方法 操作系统提供进程间通信方式的原因 因为对于我们进程来说 xff0c 每一个进程都是相互独立的 xff0c 具有独立性 xff0c 如果我们需要两个不同的进
  • linux---进程间通信(ipc)之共享内存

    前面我们讲解了进程间通信之管道 xff0c 这段我们讲解我们的共享内存 共享内存是所有进程间通信方式最快的一种 内存共享模型就像下面的图一样 xff0c 就是将物理内存映射到我们进程的虚拟地址上 xff0c 我们就可以直接操作我们虚拟地址空
  • 【进程间通信 之 通信的建立】

    目录 前言 进程间通信的目的 进程间通信的方式 管道 1 匿名管道 简单示例1 消息传输 五个特性 四种场景 简单示例2 进程控制 对管道的深入理解 2 命名管道 简单示例3 不相关进程间通信 system V 共享内存 简单示例4 通知事
  • 【iOS】UserDefaults使用的一些“坑”

    UserDefaults使用的一些 坑 项目场景 问题1 初始化程序组对应UserDefaults失败 原因分析 问题2 没有记录数据的时候 读取值为0 or false 导致配置使用时错误 原因分析 问题3 extension进程中监听需
  • 什么事IPC(Inter-Process Communication,进程间通信)

    进程间通信IPC 也就是Inter Process Communication的缩写 首先我们明白一个进程其实就是一个狭义上的程序 一个服务器也就是一个进程 比如客户端和服务器的连接就是两个进程在通信 只是这两个进程并不在同一台计算机上 它
  • 面试了这么多场,“ 进程间的通信 ” 真是从不缺席,小伙伴们赶快重视起来!!

    进程间通信 1 管道 2 消息队列 3 共享内存 4 信号量 5 信号 6 Socket 套接字 每个进程的用户地址空间都是独立的 一般而言是不能互相访问的 但内核空间是每个进程都共享的 所以进程之间要通信必须通过内核 在内核中开辟一块缓冲
  • qt子进程和父进程读写数据通信

    进程A 例如主程序 创建了一个进程 B 这个B就称为A的子进程 而A称为B的父进程 这也称为进程间通信 有多种方式 TCP IP Local Server Socket 共享内存 D Bus Unix库 QProcess 会话管理 这里 因
  • 进程间通讯的7种方式

    1 常见的通信方式 管道pipe 管道是一种半双工的通信方式 数据只能单向流动 而且只能在具有亲缘关系的进程间使用 进程的亲缘关系通常是指父子进程关系 命名管道FIFO 有名管道也是半双工的通信方式 但是它允许无亲缘关系进程间的通信 消息队

随机推荐

  • GNOME图形界面的基本操作

    成功登录进入CentOS系统之后 xff0c 我们首先看到的桌面就是GNOME图形界面 xff0c 下面来看一下相关的基本操作 个性化设置 1 xff0c 设置屏幕分辨率 进入菜单 2 xff0c 更换桌面背景 进入下面菜单 选择一张背景图
  • 连接服务器VNC

    1 xff0c 启动vnc vncserver 2 xff0c 提示输入密码 3 xff0c Would you like to enter a view only password y n 选择n 4 xff0c 会生成一个端口号 5 更
  • Android基础知识(七):Activity互调之间的生命周期变化与onNewIntent()触发机制

    Android基础知识 xff08 七 xff09 xff1a Activity互调之间的生命周期变化与onNewIntent 触发机制 一 Activity切换的生命周期 前面Android基础知识 xff08 五 xff09 xff1a
  • 二叉树节点和度的关系及特点

    写在前边的话 xff1a 你的支持是我写作的动力 xff0c 有帮助到你的话麻烦点赞 加收藏 呦 感激不尽 xff01 如有错误也请留言指正 目录 一 完全二叉树 节点总数的特点 二 二叉树 度的特点 1 n0与n2的关系 2 节点总数和度
  • 平衡二叉树的最大深度和最少节点数

    写在前边的话 xff1a 你的支持是我写作的动力 xff0c 有帮助到你的话麻烦点赞加收藏呦 感激不尽 xff01 如有错误也请留言指正 考研数据结构练习 xff0c 欢迎订阅我的专辑 考研数据结构题型分类讲解练习 目录 一 知识点 二 例
  • dataturks解析

    34 34 34 根据大json写小json 34 34 34 with open 39 pay json 39 as f datas 61 f readlines for data in datas data 61 data strip
  • STM32串口之环形队列接收数据

    原文链接 xff1a STM32串口之环形队列接收数据 码代码的应该学数据结构都学过队列 环形队列是队列的一种特殊形式 xff0c 应用挺广泛的 因为有太多文章关于这方面的内容 xff0c 理论知识可以看别人的 xff0c 下面写得挺好的
  • Linux使用ssh远程登陆

    什么是SSH xff1f 简单说 xff0c SSH是一种网络协议 xff0c 用于计算机之间的加密登录 如果一个用户从本地计算机 xff0c 使用SSH协议登录另一台远程计算机 xff0c 我们就可以认为 xff0c 这种登录是安全的 x
  • 使用Vscode 编译 开发 调试 STM32单片机 VScode+openocd+STM32CubeMX+GDB

    Vscode 编译 开发 调试 STM32单片机 为什么记录这篇文章环境准备软件及工具下载软件安装 VScode功能搭建使用STM32CubeMX生成带有makefile的工程配置VScode工程 使用vscode 开发 xff0c 编译
  • 出错信息“module or group tools is not avaliable”

    出错信息 module or group tools is not avaliable 使用yum安装软件时 xff0c 有时会出现这个问题 xff0c 可能是需要安装的软件来自第三方 解决办法 yum install epel relea
  • ubuntu 自动登录/图形界面启动流程

    ubuntu 自动登录 图形界面启动流程 启动流程配置greeter和desktop自动登录配置自动登录后进入的desktop总结 这两天在Jetson nano 上想做一个跳过用户界面直接自动登录到桌面的功能 本来很简单的在System
  • Ubuntu update-alternatives 安装/管理多版本 Python3及PIP3

    Ubuntu update alternatives 安装 管理多版本 Python3及PIP3 前言安装python安装对应版本pipupdate alternatives 切换python3 环境 前言 在ubuntu系统上 xff0c
  • 实用的Visual Studio Code插件

    1 vscode color highlight 颜色代码高亮插件 xff08 sublime text也有 xff09 2 vscode Open in Browser 右键在浏览器打开 xff08 sublime text也有 xff0
  • LWIP 双IP实现

    LwIP是Light Weight 轻型 IP协议 xff0c 有无操作系统的支持都可以运行 LwIP实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用 xff0c 它只需十几KB的RAM和40K左右的ROM就可以运行 xff
  • Seata解析-seata部署启动初体验

    本文基于seata 1 3 0版本 seata是由阿里巴巴开源的分布式事务框架 xff0c 用于在分布式环境中保持事务一致性 它提供了四种事务模式 xff1a AT TCC SAGA 和 XA 事务模式 xff0c 默认是AT模式 Seat
  • 功能案例----java实现语音播报功能

    功能案例 java实现语音播报功能 根据自己最近的写的项目 xff0c 总结整理了关于java语音播报功能的方法 xff0c 可分为两种形式 一种是通过自己写出一个语音播报方法的工具类 xff0c 然后从前端获取文本数据 xff0c 最后跳
  • spring mvc拦截器 需求:在controller层的方法上,使用自定义注解的方式 不拦截指定请求

    原来是在controller类上实现此需求 缺点 xff1a 只能是整个controller类下的方法全部放开拦截 xff0c 不能放开其中某个方法 xff0c 颗粒度太高 现实现在方法上增加注解 xff0c 更加细颗粒度 1 首先是自定义
  • 生产者消费者代码实现(JAVA)

    代码 import lombok extern slf4j Slf4j import java util LinkedList final class Message 单条消息 private int id private String m
  • 手误删除服务器tomcat下的bin目录,./start.sh无效

    关于LINUX权限 bash startup sh Permission denied 在执行 startup sh 或者 shutdown sh的时候 xff0c 爆出了Permission denied xff0c 其实很简单 xff0
  • C++ 进程间通信

    一 xff0c C 43 43 常用进程间通信 管道 Pipe xff1a 管道可用于具有亲缘关系进程间的通信 xff0c 允许一个进程和另一个与它有共同祖先的进程之间进行通信 命名管道 named pipe xff1a 命名管道克服了管道