QT进程间通信极简版(仅支持传递消息类型)

文中报错头文件,均可在往期博客获取
使用方式,两个进程创建通信的标识
CIPCManager::GetInstance()->CreateIPC(shutdownMsg);
接收端启用一个线程,调用RecvMsg或RecvAck等待消息
发送端调用SendMsg或SendAck发送消息

IPC.h

#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QSharedPointer>
#include "BlockingQueue.h"

class CIPC
{
public:
	CIPC(QString identify);
public:
	void SendMsg(int msg = -1);
	int RecvMsg();
	void SendAck(int ack);
	int RecvAck();
private:
	QString m_identify;
	QSharedPointer<QSharedMemory> m_memeory;
	QSharedPointer<QSystemSemaphore> m_msgSemaphore;
	QSharedPointer<QSystemSemaphore> m_ackSemaphore;
};

enum EIPCMsg
{
	SHORTCUT_ENABLE,
	SHORTCUT_DISABLE,

	SHUTDOWN_VIEW_BTN_CLICKED,
	SHUTDOWN_HAREWARE_BTN_CLICKED,
	SHUTDOWN_EXEC,
};

constexpr char* shortcutKeys = "shortcutKeys";
constexpr char* shutdownMsg = "shutdownMsg";

class CIPCManager
{
public:
	void CreateIPC(QString identify);

	static CIPCManager* GetInstance() {
		static CIPCManager i;
		return &i;
	}

	QSharedPointer<CIPC> operator[](QString identify) {
		return m_ipcs[identify];
	}
private:
	CIPCManager() = default;
	QHash<QString, QSharedPointer<CIPC>> m_ipcs;
};

IPC.cpp

#include "IPC.h"
#include "Log.h"

constexpr int MSG_SIZE{ 4 };
constexpr int ACK_SIZE{ 4 };

CIPC::CIPC(QString identify)
	:m_identify(identify),
	m_memeory(new QSharedMemory(identify.append("_sharedmemory")),
		[](QSharedMemory* memory) { if (memory->isAttached()) { memory ->detach(); delete memory; }}),
	m_msgSemaphore(new QSystemSemaphore(identify.append("_msg_semaphore"))),
	m_ackSemaphore(new QSystemSemaphore(identify.append("_ack_semaphore")))
{
	bool res = m_memeory->create(MSG_SIZE + ACK_SIZE);
	if (res) {
		LogInfo << m_identify.toStdString() << " memory create.";
	}
	if (!res && m_memeory->error() == QSharedMemory::SharedMemoryError::AlreadyExists) {
		LogInfo << m_identify.toStdString() << " memory exist.";
		m_memeory->attach();
	}
}

void CIPC::SendMsg(int msg)
{
	LogInfo << m_identify.toStdString() << " send msg:" << msg;
	m_memeory->lock();
	*reinterpret_cast<int*>(m_memeory->data()) = msg;
	m_memeory->unlock();
	m_msgSemaphore->release();
}

int CIPC::RecvMsg()
{
	LogInfo << m_identify.toStdString() << " wait msg";
	m_msgSemaphore->acquire();
	int msg{-1};
	m_memeory->lock();
	msg = *reinterpret_cast<int*>(m_memeory->data());
	m_memeory->unlock();
	LogInfo << m_identify.toStdString() << " recv msg:" << msg;
	return msg;
}

void CIPC::SendAck(int ack)
{
	LogInfo << m_identify.toStdString() << " send ack:" << ack;
	m_memeory->lock();
	*(reinterpret_cast<int*>(m_memeory->data()) + 1) = ack;
	m_memeory->unlock();
	m_ackSemaphore->release();
}

int CIPC::RecvAck()
{
	LogInfo << m_identify.toStdString() << " wait ack";
	m_ackSemaphore->acquire();
	int ack{};
	m_memeory->lock();
	ack = *(reinterpret_cast<int*>(m_memeory->data()) + 1);
	m_memeory->unlock();
	LogInfo << m_identify.toStdString() << " recv ack:" << ack;
	return ack;
}

void CIPCManager::CreateIPC(QString identify)
{
	QSharedPointer<CIPC> p(new CIPC(identify));
	m_ipcs.insert(identify, std::move(p));
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flower980323

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值