文中报错头文件,均可在往期博客获取
使用方式,两个进程创建通信的标识
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));
}