进程间的通信

本文介绍了在Windows和Linux环境下实现进程间通信的各种方法,包括Windows下的导出函数+PE可写段、共享内存、命名管道、电子邮件槽、文件映射和套接字,以及Linux下的pipe、FIFO、消息队列、信号量和共享内存。详细讲解了每种通信方式的工作原理和使用场景。
摘要由CSDN通过智能技术生成

windows环境

1.利用导出函数+PE可写段

在这里插入图片描述

#ifndef TEST_DLL_MAIN_CPP_
#define TEST_DLL_MAIN_CPP_
/*
* test_dll_main.cpp
*/

#include <windows.h>
#include <string>
#include "log/logx.h"
using namespace std;
#define  DLLEXPORT extern "C" __declspec(dllexport)
#pragma data_seg("share_seg")
DLLEXPORT  char share_data[13] = "hello world!";
#pragma  data_seg()

#pragma  comment(linker,"/SECTION:share_seg,RWS")

DLLEXPORT void test001() {
   
	LOGXA("hello world");
}

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID _reserced) {
   
	switch (reason){
   
	case DLL_PROCESS_ATTACH: {
   
		LOGXD("load dll",__LINE__, __FILE__);
		break;
	}
	case DLL_PROCESS_DETACH: {
   
		LOGXD("unload dll", __LINE__, __FILE__);
		break;
	}
	default:
		break;
	}
	return TRUE;
}

#endif //_TEST_DLL_MAIN_CPP_


#ifndef TEST_MAIN_CPP_
#define TEST_MAIN_CPP_
/*
* test_main.cpp
*/
#include <iostream>
#include <string>
#include "log/logx.h"
using namespace  std;

int main() {
   
	string file_name(R"(C:\Desktop\t\exe\TestDll.dll)");
	HMODULE lib= LoadLibraryA(file_name.data());
	if (lib == nullptr) {
   
		LOGXF(VAR_DATA(GetLastError()));
		return 1;
	}
	auto addr = GetProcAddress(lib, "test001");
	DWORD addr2 =(DWORD) GetProcAddress(lib, "share_data");
	LOGXD((char*)addr2);
	((void(*)())addr)();
	return 0;
}
#endif //_TEST_MAIN_CPP_



#ifndef TEST_EXE_MAIN_CPP_
#define TEST_EXE_MAIN_CPP_
/*
* test_exe_main.cpp
*/
#include <iostream>
#include <string>
#include "log/logx.h"
using namespace  std;

int main() {
   
	string file_name(R"(C:\Desktop\t\exe\TestDll.dll)");
	HMODULE lib = LoadLibraryA(file_name.data());
	if (lib == nullptr) {
   
		LOGXF(VAR_DATA(GetLastError()));
		return 1;
	}
	auto addr = GetProcAddress(lib, "test001");
	char* addr2 = (char*)GetProcAddress(lib, "share_data");
	LOGXD((char*)addr2);
	memmove(addr2, "123", 3);
	LOGXD((char*)addr2);
	((void(*)())addr)();
	Sleep(-1);
	return 0;
}
#endif //_TEST_EXE_MAIN_CPP_

2.共享内存,加上了同步机制

在这里插入图片描述

#pragma once
#ifndef SHAREMEMORY_H_
#define SHAREMEMORY_H_
/*
* ShareMemory.h
*/

class ShareMemoryPimpl;
class ShareMemory{
   
public:
	ShareMemory();
	~ShareMemory();
	bool initEnv();
	int sendData(const char* _data, int _size);
	void test();
private:
	ShareMemoryPimpl* m_imp = nullptr;

};

#endif //_SHAREMEMORY_H_


#include "ShareMemory.h"
#include <string>
#include "log/logx.h"
#include <windows.h>
using namespace std;

class ShareMemoryPimpl {
   
public:
	//控制的读写事件,假设存在两个内存块,则2*2个事件比较好控制,进程之间由于两个内存块也比较方便数据的传输
	//这里仅仅是写事件,另外的进程读,数据单项传输,如果想双向,可以两个内存块

	HANDLE m_share_handle = nullptr;
	HANDLE m_write_event = nullptr;
	HANDLE m_read_event = nullptr;
	const char* m_write_event_name = "write_event";
	const char* m_read_event_name = "read_event";
	//内存块
	void* m_share_memory_addr = nullptr;
	const int m_share_memory_size = 1024;
	const char* m_share_memory_name = "share_memory";
};

ShareMemory::ShareMemory() {
   
	m_imp = new ShareMemoryPimpl;
	if (initEnv() == false) {
   
		LOGXF("init env fail");
		exit(0);
	}
	LOGXD("open share memory succeed","name:", m_imp->m_share_memory_name,"size:",m_imp->m_share_memory_size);
}

ShareMemory::~ShareMemory() {
   
	UnmapViewOfFile(m_imp->m_share_memory_addr);
	CloseHandle(m_imp->m_share_handle);
	delete m_imp;
}

bool ShareMemory::initEnv() {
   
	/*
	*/
	do {
   
		m_imp->m_write_event = CreateEventA(nullptr, true, false, m_imp->m_write_event_name);
		m_imp->m_read_event = CreateEventA(nullptr, true, false, m_imp->m_read_event_name);
		ResetEvent(m_imp->m_write_event);//now ,not to read and not to write ,wait client write event
		ResetEvent(m_imp->m_read_event);
		m_imp->m_share_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0,m_imp->m_share_memory_size, m_imp->m_share_memory_name);
		if (m_imp->m_share_handle == NULL) {
    
			LOGXF(VAR_DATA(GetLastError()));
			break;
		}
		m_imp->m_share_memory_addr = MapViewOfFile(m_imp->m_share_handle, FILE_MAP_ALL_ACCESS,0, 0, 0);

	} while (false);
	return m_imp->m_share_memory_addr;
}

int ShareMemory::sendData(const char* _data, int _size) {
   
	/*
	* 1.when write ,do not read
	* send packet=data_len+data,example packet=5hello
	*
	*/
	if (_size > m_imp->m_share_memory_size-sizeof(int))return -1;
	WaitForSingleObject(m_imp->m_write_event, INFINITE);
	ResetEvent(m_imp->m_read_event);
	memcpy(m_imp->m_share_memory_addr, &_size, sizeof(_size));
	memcpy((char*)m_imp->m_share_memory_addr+sizeof(_size), _data, _size);
	ResetEvent(m_imp->m_write_event);
	SetEvent(m_imp->m_read_event);
	return 0;
}

void ShareMemory::test() {
   
	for (int i = 0; i < 20; i++) {
   
		string data = to_string(i);
		sendData(data.data(), data.size());
		LOGXD("send:", VAR_DATA(data));
	}

}



#pragma once
#ifndef SHAREMEMORYCLIENT_H_
#define SHAREMEMORYCLIENT_H_
/*
* ShareMemoryClient.h
*/
class ShareMemoryPimpl;
class ShareMemoryClient{
   
public:
	ShareMemoryClient();
	~ShareMemoryClient();
	bool iniEnv();
	int readData(void* buf, int max_size);
	void test();
private:
	ShareMemoryPimpl* m_imp;
};
#endif //_SHAREMEMORYCLIENT_H_


#include "ShareMemoryClient.h"
#include <windows.h>
#include "log/logx.h"
class ShareMemoryPimpl {
   
public:
	
	HANDLE m_share_handle = nullptr;
	HANDLE m_write_event = nullptr;
	HANDLE m_read_event = nullptr;
	const char* m_write_event_name = "write_event";
	const char* m_read_event_name = "read_event";
	//内存块
	void* m_share_memory_addr = nullptr;
	const int m_share_memory_size = 1024;
	const char* m_share_memory_name = "share_memory";
};

ShareMemoryClient::ShareMemoryClient(){
   
	m_imp = new ShareMemoryPimpl;
	if (iniEnv() == false) {
   
		LOGXF("no exist share memory");
		exit(0);
	}
}

ShareMemoryClient::~ShareMemoryClient(){
   
	UnmapViewOfFile(m_imp->m_share_memory_addr);
	CloseHandle(m_imp->m_share_handle);
	delete m_imp;
}

bool ShareMemoryClient::iniEnv(){
   
	m_imp->m_read_event = OpenEventA(EVENT_ALL_ACCESS, false, m_imp->m_read_event_name);
	m_imp->m_write_event = OpenEventA(EVENT_ALL_ACCESS, false, m_imp->m_write_event_name);
	SetEvent(m_imp->m_write_event);//tell server can write
	ResetEvent(m_imp->m_read_event);
	m_imp->m_share_handle= OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, m_imp->m_share_memory_name);
	m_imp->m_share_memory_addr = MapViewOfFile(m_imp->m_share_handle, FILE_MAP_ALL_ACCESS,0, 0,0);
	return m_imp->m_share_memory_addr&& 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值