【Qt】进程间通信之QSharedMemory示例
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 開發環境
- 03. 編程步驟
- 04. 寫端程序示例
- 05. 讀端程序示例
- 06. 附錄
01. 概述
QSharedMemory提供了多個線程和進程對共享內存段的訪問。它還提供了一種方法,讓單個線程或進程鎖定內存以進行獨占訪問。
當使用這個共享內存類時,請注意以下平臺差異:
Windows:QSharedMemory 不“擁有”共享內存段。當所有具有連接到特定共享內存段的 QSharedMemory 實例的線程或進程已銷毀其 QSharedMemory 實例或退出時,Windows 內核會自動釋放共享內存段。
Unix:QSharedMemory“擁有”共享內存段。當將 QSharedMemory 實例附加到特定共享內存段的最后一個線程或進程通過銷毀其 QSharedMemory 實例與該段分離時,Unix 內核會釋放共享內存段。但是如果最后一個線程或進程在沒有運行 QSharedMemory 析構函數的情況下崩潰,共享內存段會在崩潰中幸存下來。
HP-UX:每個進程只允許一個連接到共享內存段。這意味著 QSharedMemory 不應跨 HP-UX 中同一進程中的多個線程使用。
記得在對共享內存進行讀寫之前用lock ()鎖住共享內存,完成后記得用unlock ()釋放鎖。
當 QSharedMemory 的最后一個實例與段分離時,QSharedMemory 會自動銷毀共享內存段,并且不會保留對該段的引用。
02. 開發環境
Windows系統:Windows10
Qt版本:Qt5.15或者Qt6
03. 編程步驟
共享內存中數據提供方:
A、定義QSharedMemory shareMemory,并設置標志名shareMemory.setKey();
B、將共享內存與主進程分離 shareMemory.detach();
C、創建共享內存 shareMemory.create();
D、將共享內存上鎖shareMemory.lock();
E、將進程中要共享的數據拷貝到共享內存中;
F、將共享內存解鎖shareMemory.unlock();
共享內存中數據使用方:
A、定義QSharedMemory shareMemory,并設置與共享內存提供方一致的標志名shareMemory.setKey()。
B、將共享內存與主進程綁定shareMemory.attach(),使主進程可以訪問共享內存的數據;
C、將共享內存上鎖shareMemory.lock();
D、從共享內存中取數據;
E、使用完后將共享內存解鎖shareMemory.unlock(),并將共享內存與進程分離shareMemory.detach();
04. 寫端程序示例
widget.h文件
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QSharedMemory>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;QSharedMemory *m_sharedMemory = nullptr; }; #endif // WIDGET_Hwidget.cpp文件
#include "widget.h" #include "ui_widget.h"#include <QDebug> #include <QString> #include <QFileDialog> #include <QImage> #include <QBuffer> #include <QDataStream>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//創建對象 設置Keym_sharedMemory = new QSharedMemory;m_sharedMemory->setKey("Kitty");}Widget::~Widget() {delete ui; }//選擇圖片按鈕槽函數 void Widget::on_pushButton_clicked() {//如果指定Key共享內存已經關聯,則解除關聯if (m_sharedMemory->isAttached()){if (!m_sharedMemory->detach()){qDebug() << m_sharedMemory->errorString();return;}}//選擇圖片文件QString fileName = QFileDialog::getOpenFileName(this, "", "", "Images(*.*)");QImage image(fileName);ui->label->setPixmap(QPixmap::fromImage(image).scaled(256, 256));QBuffer buffer;buffer.open(QBuffer::ReadWrite);QDataStream out(&buffer);out << image;//創建共享內存if (!m_sharedMemory->create(buffer.size())){qDebug() << m_sharedMemory->errorString();return;}//加鎖m_sharedMemory->lock();char *data = (char *)m_sharedMemory->data();const char *from = buffer.data().data();memcpy(data, from, qMin(m_sharedMemory->size(), (int)buffer.size()));//解鎖m_sharedMemory->unlock();}main.cpp文件
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }執行結果如下:
05. 讀端程序示例
widget.h文件
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QSharedMemory>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;QSharedMemory *m_sharedMemory = nullptr;}; #endif // WIDGET_Hwidget.cpp文件
#include "widget.h" #include "ui_widget.h"#include <QDebug> #include <QBuffer> #include <QDataStream> #include <QImage> #include <QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//m_sharedMemory = new QSharedMemory("Kitty");m_sharedMemory = new QSharedMemory;m_sharedMemory->setKey("Kitty");}Widget::~Widget() {delete ui; }//讀取共享內存槽函數 void Widget::on_pushButton_clicked() {//關聯共享內存if (m_sharedMemory->attach()){qDebug() << "關聯共享內存成功";}else{qDebug() << m_sharedMemory->errorString();return;}QBuffer buffer;QDataStream in(&buffer);QImage image;//加鎖m_sharedMemory->lock();buffer.setData((char*)m_sharedMemory->constData(), m_sharedMemory->size());buffer.open(QBuffer::ReadOnly);in >> image;//解鎖m_sharedMemory->unlock();//共享內存解除關聯if (!m_sharedMemory->detach()){qDebug() << m_sharedMemory->errorString();return;}ui->label->setPixmap(QPixmap::fromImage(image));}main.cpp文件
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }執行結果如下
06. 附錄
6.1 Qt教程匯總
網址:https://dengjin.blog.csdn.net/article/details/115174639
6.2 程序下載
下載:【Qt】進程間通信之QSharedMemory程序.rar
總結
以上是生活随笔為你收集整理的【Qt】进程间通信之QSharedMemory示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Qt】QSharedMemory类详解
- 下一篇: 【Tools】RDB打包工具详解