来源:https://www.devbean.net/2013/11/qt-study-road-2-ipc/
Qt 提供了四种进程间通信的方式:
1.使用共享内存(shared memory)交互:这是 Qt 提供的一种各个平台均有支持的进程间交互的方式。
2.TCP/IP:其基本思想就是将同一机器上面的两个进程一个当做服务器,一个当做客户端,二者通过网络协议进行交互。除了两个进程是在同一台机器上,这种交互方式与普通的 C/S 程序没有本质区别。Qt 提供了 QNetworkAccessManager 对此进行支持。
3.D-Bus:freedesktop 组织开发的一种低开销、低延迟的 IPC 实现。Qt 提供了 QtDBus 模块,把信号槽机制扩展到进程级别(因此我们前面强调是“普通的”信号槽机制无法实现 IPC),使得开发者可以在一个进程中发出信号,由其它进程的槽函数响应信号。
4.QCOP(Qt COmmunication Protocol):QCOP 是 Qt 内部的一种通信协议,用于不同的客户端之间在同一地址空间内部或者不同的进程之间的通信。目前,这种机制只用于 Qt for Embedded Linux 版本。
构造函数初始化列表中我们将sharedMemory成员变量进行初始化。注意我们给出一个键(Key),前面说过,我们可以把QSharedMemory看做是指向系统共享内存段的指针,而这个键就可以看做指针的名字。多个线程或进程使用同一个共享内存段时,该键值必须相同。
.h文件中定义
const char *KEY_SHARED_MEMORY = "Shared";
main.cpp中
sharedMemory = new QSharedMemory(KEY_SHARED_MEMORY,this);
共享内存步骤:
1.将文件写入共享内存:
QPixmap pixmap(fileName);
ui->label->setPixmap(pixmap);
//QBuffer 是一个文件读写界面。但文件是存在内存中的
//1.申请QBuffer
QBuffer buffer;
//2.将buffer写入data流中
QDataStream out(&buffer);
//3.buffer读写操作 利用QBuffer将图片数据转化为char * 格式
buffer.open(QBuffer::ReadWrite);
//4.将pixmap写入QDataStream
out<<pixmap;
//5.定义size = buffer.size()
int size = buffer.size();
//6.判断sharedMemory是否已经创建
if(!sharedMemory->create(size)){
qDebug()<<(tr("Unable to create memory segment."))<< sharedMemory->errorString();
}else{
//7.在读取或写入共享内存时,都需要使用QSharedMemory::lock()函数对共享内存段加锁
sharedMemory->lock();
//8.定义char变量 一个接受sharedMemory 一个接收buffer数据
char *to = static_cast<char*>(sharedMemory->data());
const char *from = buffer.data().constData();
//共享内存段就是一段普通内存,用C语言标准函数memcpy()复制内存段。
//9.将bufffer 数据写入共享内存中
memcpy(to,from,qMin(size,sharedMemory->size()));
//10.解锁共享内存段
sharedMemory->unlock();
qDebug()<<"shared memory has created";
}
2.读取共享内存
void MainWindow::loadFromMemory()
{
//因为QSharedMemory在同一个进程中,由于之前调用create()函数在系统内核中创建该了共享内存,与此同时相当于调用了一次attach(),
//而该函数在同一个进程中在没有detach()之前再次attach()就会失败;
//但是失败并不意味着出错,此时需要再判断error() == QSharedMemory::NoError 才可以完全判断是否出错.
// if(sharedMemory->attach()){
// qDebug()<<tr("Attach Error")<<sharedMemory->errorString();
// }else{
QBuffer buffer;
QDataStream in(&buffer);
QPixmap pixmap;
//sharedMemory先加锁 后解锁
sharedMemory->lock();
buffer.setData(static_cast<const char*>(sharedMemory->constData()),sharedMemory->size());
buffer.open(QBuffer::ReadWrite);
in>>pixmap;
sharedMemory->unlock();
sharedMemory->detach();
ui->label_2->setPixmap(pixmap);
//}
}