IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> C++多进程通信、信号量、内存共享 -> 正文阅读

[系统运维]C++多进程通信、信号量、内存共享

概述

说明:本文所述方法基于windows操作系统实现多进程通信,实现进程间同步、传递图像数据。
知识点:C++、信号量、共享内存、多进程。

进程间通信

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

代码实现

使用C++实现两个进程之间通信:

1:使用共享内存实现两个进程之间传递数据
2:使用信号量实现两个进程同步
共享内存传递int、vector、图像
思路:父进程将需要发送的数据拷贝到申请的共享内存中,子进程从共享内存中把数据拷贝到本地。
注意:函数memcpy(lpBase, &arr[0], 8);在执行时,参数定义如下:
1:目标地址
2:源起始地址
3:拷贝的字节数
因此在传递vector变量时我们需要传入的第二个变量是&arr[0],因为这才是动态数组的起始地址,而&arr是vector对象的地址,并不是数组的起始地址
拷贝的字节数,因为int占4个字节,因此我们把从&arr[0]开始的8个字节的内容复制到共享内存中。
在传递图像数据时,我这里采取的方法是,父进程对图像编码,存入共享内存,子进程读出数据后解码。
子进程在接收数据时,需要提前申请空间
vector arr(2);
std::vector jpg_buff(15676);
BUF_SIZE, 为文件大小,所传递的数据量不能大于BUF_SIZE。

父进程

// 定义共享数据
//联合Opencv传递图像数据
cv::Mat std;
cv::Mat hel;
std = cv::imread(“hello.jpg”);
cv::Mat dst_mat = std(cv::Rect(0, 0, 250, 250));
std::vector jpg_buff;
bool ret = cv::imencode(“.jpg”, dst_mat, jpg_buff);
//传递整形数据
int a;
//传递数组
vectorarr;
arr.pushback(211);
arr.pushback(311);
///hel=cv::imdecode(jpg_buff,0);
//cv::imwrite(“000.jpg”, hel);
/

// 创建共享文件句柄
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // 物理文件句柄
NULL, // 默认安全级别
PAGE_READWRITE, // 可读可写
0, // 高位文件大小
BUF_SIZE, // 定义文件大小
L"Sharememory" // 共享内存名称
);

// 映射缓存区视图 , 得到指向共享内存的指针
LPVOID lpBase = MapViewOfFile(
hMapFile, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
BUF_SIZE//定义文件大小
);

// 将数据拷贝到共享内存
//传递整形数据
memcpy(lpBase, &a, 4);

    //传递数组
    memcpy(lpBase, &arr[0], 8);
    //传递图片
    memcpy(lpBase, &jpg_buff[0], 15676);

线程挂起等其他线程读取数据
Sleep(15000);

解除文件映射
UnmapViewOfFile(lpBase);
关闭内存映射文件对象句柄
CloseHandle(hMapFile);

子进程:

// 打开共享的文件对象
HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, L"Sharememory");
//申请变量准备接收数据
vector arr(2);
int a = 0;
std::vector jpg_buff(15676);

if (hMapFile) {
 
	LPVOID lpBase= MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	cv::Mat hel;
            //以下三种数据和父进程发送的数据要一一对应
	memcpy(&jpg_buff[0], lpBase, 15676);
	memcpy(&a, lpBase, 4);
            memcpy(&arr[0], lpBase, 4);
            
            //图像解码
	hel = cv::imdecode(jpg_buff, 0);
	cv::imwrite("009.jpg", hel);

	// 解除文件映射
	UnmapViewOfFile(lpBase);
	// 关闭内存映射文件对象句柄
	CloseHandle(hMapFile);
}
else {
	// 打开共享内存句柄失败
	cout << "打开共享失败!" << endl;

}

信号量实现进程同步

信号量通信较为简单,使用时应注意以下几点:
1:ReleaseSemaphore(myHSemaphore, 1, NULL);相当于发送一次消息
2:WaitForSingleObject(myHSemaphore, INFINITE);相当于消耗一次消息

父进程:

//信号量
HANDLE myHSemaphore;

myHSemaphore = CreateSemaphore(NULL, FALSE, TRUE, TEXT("TOCHILD"));
if (myHSemaphore == NULL)
{
	
	AfxMessageBox(TEXT("ERROR"));
	return;
}
Sleep(5000);
ReleaseSemaphore(myHSemaphore, 1, NULL);

Sleep(2000);
WaitForSingleObject(myHSemaphore, INFINITE);

CloseHandle(myHSemaphore);

AfxMessageBox(TEXT("OK"));

子进程:

HANDLE myHSemaphore;
myHSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, TEXT(“TOCHILD”));
if (myHSemaphore == NULL)
{
return FALSE;
}
std::cout << "waiting " << std::endl;

WaitForSingleObject(myHSemaphore, INFINITE);

std::cout << "had waited " << std::endl;

ReleaseSemaphore(myHSemaphore, 1, NULL);
Sleep(500);
CloseHandle(myHSemaphore);

return TRUE;
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 12:00:08  更:2022-05-13 12:01:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 15:50:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码