1. 程式人生 > >Qt提供通過訪問共享記憶體實現程序間通訊

Qt提供通過訪問共享記憶體實現程序間通訊

② 通過建構函式QSharedMemory::QSharedMemory (QObject * parent = 0 )構造例項物件,之後呼叫setKey()函式為該例項物件設定關鍵字。

例如:

QSharedMemorysharememory;

sharememory = new QSharedMemory();

sharememory->setKey("QSharedMemoryExample ");

2、建立共享記憶體

boolQSharedMemory::createintsizeAccessModemode=ReadWrite )

為QSharedMemory類例項物件建立一個空間大小為size

的共享記憶體,該記憶體空間預設的訪問方式為可讀可寫。共享記憶體建立成功返回true,否則返回false。QSharedMemory類定義一個列舉類變數AccessMode,指定了兩種共享記憶體的訪問方式:

QSharedMemory::ReadOnly   只讀方式訪問共享記憶體

QSharedMemory::ReadWrite  讀寫方式訪問共享記憶體

3、關聯共享記憶體

boolQSharedMemory::attachAccessModemode=ReadWrite )

將以關鍵字key命名的共享記憶體和當前程式進行關聯,共享記憶體預設的訪問方式為可讀可寫。如果程式和共享記憶體關聯成功,返回true,否則返回false。

4、分離共享記憶體

boolQSharedMemory::detach()

解除共享記憶體和程式的關聯,即呼叫該函式後,程式不可以再訪問共享記憶體。如果該共享記憶體被多個程式例項所關聯,當最後一個程式例項和共享記憶體解除關聯後,該共享記憶體將由作業系統自動釋放掉。分離操作成功,返回true。如果返回false,通常意味著該共享記憶體和程式分離失敗,或者其他程式當前正在訪問該共享記憶體,分離操作執行失敗。

5、判斷共享記憶體的關聯狀態

boolQSharedMemory::isAttached()const

該函式用來判斷程式(呼叫該函式的程式)是否和共享記憶體進行關聯,是返回true,否返回false。

6、設定/獲取共享記憶體的關鍵字

QStringQSharedMemory::key()const                                 //獲取共享記憶體關鍵字

Qt應用程式通過關鍵字來辨識共享記憶體。key()函式用來獲取共享記憶體的關鍵字,如果沒有指定例項物件的關鍵字,或者共享記憶體的關鍵字是由nativeKey ()函式指定的話,則返回空。 

voidQSharedMemory::setKey(const QStringkey )        //設定共享記憶體關鍵字

setKey ()函式用來為共享記憶體段設定關鍵字(為共享記憶體命名),如果引數key的值和建構函式或者之前指定的關鍵字相同的話,則該函式將不做任何操作,直接返回。

7、鎖定/解鎖共享記憶體

boolQSharedMemory::lock()                    //鎖定共享記憶體

如果共享記憶體資源當前處於釋放狀態,程序呼叫該函式將共享記憶體中的資源鎖定,並返回true。其他程序將不能訪問該共享記憶體。如果共享記憶體被其他程序佔用時,則該函式會一直處於阻塞狀態,直到其他程序使用完畢,釋放共享記憶體資源。

boolQSharedMemory::unlock()         //解鎖共享記憶體

如果共享記憶體資源被當前程序所佔有,呼叫該函式將解鎖該共享資源,並返回true。如果當前程序沒有佔用該資源,或者共享記憶體被其他程序訪問,則不做任何操作並返回false。

為了保證共享記憶體中資料的完整性,當一個程序在讀寫共享記憶體的時候,其他程序不允許對該共享區域進行訪問。QSharedMemory類提供了lock()函式和unlock()函式來實現這一共享記憶體訪問機制。某一程式對共享記憶體進行讀寫操作之前,需要呼叫lock()函式鎖定該共享記憶體,之後獨享共享記憶體中的資料,並對資料進行讀寫等操作。共享記憶體訪問完畢,呼叫unlock()函式,釋放共享記憶體的使用許可權。

8、錯誤原因

SharedMemoryErrorQSharedMemory::error()const 

當共享記憶體出錯時,呼叫該函式顯示相應的錯誤程式碼。

QStringQSharedMemory::errorString()const

當共享記憶體出錯時,呼叫該函式,以文字形式顯示錯誤原因。

9、獲取共享記憶體的地址

const void*QSharedMemory::constData()const

void* QSharedMemory::data()

const void*QSharedMemory::data()const          //過載函式

程式關聯共享記憶體的前提下,呼叫該函式返回共享記憶體中資料的起始地址。如果沒有關聯共享記憶體,則返回0。

10、獲取共享記憶體的大小

intQSharedMemory::size()const

呼叫該函式將返回程式所關聯的共享記憶體的大小(位元組)。如果沒有關聯的共享記憶體,則返回0。

二、示例程式碼

 main.cpp原始檔

#include<QtGui/QApplication>
#include"dialog.h"
#include<QTextCodec>
intmain(intargc,char*argv[])
{
QApplicationapplication(argc,argv);
//Qt國際化顯示
QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030"));
Dialogdialog;
dialog.show();
returnapplication.exec();
}

 dialog.h標頭檔案

#ifndefDIALOG_H
#defineDIALOG_H
#include<QDialog>
//除錯用標頭檔案
#include<QDebug>
#include<QMessageBox>
#include<QFileDialog>
#include<QDir>
#include<QPixmap>
#include<QImage>
#include<QDataStream>
#include<QBuffer>
#include<QSharedMemory>
namespaceUi{
classDialog;
}
classDialog:publicQDialog
{
Q_OBJECT
public:
explicitDialog(QWidget*parent=0);
~Dialog();
publicslots:
voidloadFromFile();//載入圖片按鈕響應函式
voidloadFromMemory();//顯示圖片按鈕響應函式
private:
Ui::Dialog*ui;
QSharedMemory*sharememory;//定義共享記憶體例項指標
boolfirst_flag;//判斷是否是首次載入檔案
};
#endif//DIALOG_H

 dialog.cpp原始檔

#include"dialog.h"
#include"ui_dialog.h"
#defineDEBUG//除錯開關
Dialog::Dialog(QWidget*parent):
QDialog(parent),
ui(newUi::Dialog)
{
ui->setupUi(this);
QObject::connect(ui->PBtn_Load,SIGNAL(clicked()),this,SLOT(loadFromFile()));
QObject::connect(ui->PBtn_Display,SIGNAL(clicked()),this,SLOT(loadFromMemory()));
sharememory=newQSharedMemory();//構造例項物件
sharememory->setKey("QSharedMemoryExample");//為例項物件指定關鍵字(給共享記憶體命名)
first_flag=true;
}
Dialog::~Dialog()
{
deleteui;
}
//載入圖片按鈕響應函式
voidDialog::loadFromFile()
{
if(sharememory->isAttached())//檢測程式當前是否關聯共享記憶體
sharememory->detach();//解除關聯
ui->Label_Display->setText(tr("請選擇一張圖片"));
QStringfilename=QFileDialog::getOpenFileName(
this,"開啟",QString(),tr("Image(*.png*.xpm*.jpg)"));
QImageimage;
if(!image.load(filename))//將開啟的圖片檔案和QImage例項關聯
{
ui->Label_Display->setText(tr("您選擇的不是圖片檔案,請重新選擇"));
return;
}
ui->Label_Display->setPixmap(QPixmap::fromImage(image));
QBufferbuffer;
buffer.open(QBuffer::ReadWrite);//構建並開啟資料緩衝區,訪問方式為讀寫
#ifdefDEBUG
qDebug()<<"新建緩衝區的大小為:"<<buffer.size();//測試緩衝區大小(一般為0)
#endif
QDataStreamin(&buffer);//建立資料流物件,並和緩衝區相關聯
in<<image;//向緩衝區寫入資料
intsize=buffer.size();//獲取寫入資料的大小(圖片的大小)
#ifdefDEBUG//除錯部分
qDebug()<<"緩衝區的大小為:"<<size;
qDebug()<<sharememory->key();
qDebug()<<sharememory->nativeKey();
//sharememory->setKey("共享記憶體");//修改共享記憶體的關鍵字,將無法訪問共享記憶體
qDebug()<<sharememory->key();
qDebug()<<sharememory->nativeKey();
qDebug()<<sharememory->error();
qDebug()<<sharememory->errorString();
#endif
if(true==first_flag)
{
if(!sharememory->create(size))//建立共享記憶體,大小為size
{
ui->Label_Display->setText(tr("無法建立共享記憶體段"));
qDebug()<<sharememory->errorString();
return;
}
first_flag=false;
qDebug()<<sharememory->size();//顯示共享記憶體的大小
}
//對共享記憶體進行讀寫操作
sharememory->lock();//鎖定共享記憶體
char*to=(char*)sharememory->data();//獲取共享記憶體中的地址
constchar*from=buffer.data().data();//獲取有效資料在緩衝區中的地址
memcpy(to,from,qMin(sharememory->size(),size));//將緩衝區中的資料複製到共享記憶體
sharememory->unlock();//釋放共享記憶體
}
//顯示圖片按鈕響應函式
voidDialog::loadFromMemory()
{
if(!sharememory->attach())//關聯共享記憶體
{
            
           

相關推薦

Qt提供通過訪問共享記憶體實現程序通訊

② 通過建構函式QSharedMemory::QSharedMemory (QObject * parent = 0 )構造例項物件,之後呼叫setKey()函式為該例項物件設定關鍵字。例如:QSharedMemory* sharememory;sharememory = new QSharedMemory(

Windows or Linux環境下利用“共享記憶體實現程序通訊的C/C++程式碼

程序A對應的程式: #include <iostream> #include <windows.h> using namespace std; #define BUF_SIZE 1025 char szName[] = "NameOfMappi

訊號量與共享記憶體實現程序通訊(生產者消費者問題為例)

(一)訊號量訊號量是IPC的一種,可以看做是一個計數器,計數值為可用的共享資源的數量,訊號量可用於多程序的同步,為多個程序提供對共享資源的訪問。linux下的訊號量的介面函式如下:/*(1)獲取訊號量*/int semget(key_t key, int semnum, in

共享記憶體程序通訊程序同步使用訊號量來實現

Linux 環境下C程式設計指南,通過共享記憶體進行程序間通訊的例子,程序間同步使用訊號量來實現。 程式碼 11-5 使用說明:這是一個簡單的伺服器和客戶端程式,如果啟動程式時不帶引數,則執行伺服器程式; 如果帶引數,則執行客戶端程式,所帶引數只有一個,就是伺服器端所顯

Windows上C++使用共享記憶體進行程序通訊

共享記憶體 (也叫記憶體對映檔案) 主要是通過對映機制實現的 , Windows 下程序的地址空間在邏輯上是相互隔離的 , 但在物理上卻是重疊的 ; 所謂的重疊是指同一塊記憶體區域可能被多個程序同時使用

一起talk C栗子吧(第九十五回:C語言例項--使用共享記憶體進行程序通訊一)

各位看官們,大家好,上一回中咱們說的是SystemV IPC結構概述的例子,這一回咱們說的例子是:使用共享記憶體進行程序間通訊。閒話休提,言歸正轉。讓我們一起talk C栗子吧! 共享記憶體是SystemV IPC結構這種抽象概念的一種具體物件。就和它的

Linux 通過共享記憶體機制實現程序通訊

問題背景 編寫程式 sender ,它建立一個共享記憶體,然後等待使用者通過終端輸入一串字元,並將這串字元通過共享記憶體傳送給 receiver;最後,它等待 receiver 的應答,收到應答訊息後,將接收到的應答資訊顯示在終端螢幕上,刪除共享記憶體,結束程式的執行。 編寫 receiver 程

iOS--CFMessagePort實現程序通訊

CFMessagePort屬於CoreFoundation框架中的類。因此可以在http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz中在原始碼,如果感興趣可以去看看。 下面說下CFMessagePortRef的具體使用。 首先建立一

Android BroadcastReceiver使用,可實現程序通訊

1、建立廣播接收器: /** * 作者:created by meixi * 郵箱:[email protected] * 日期:2018/11/1 09 */ public class MyBroadcastReceiver extends BroadcastReceiver

C#使用SendMessage實現程序通訊的方法

本文例項講述了C#使用SendMessage實現程序間通訊的方法。分享給大家供大家參考。具體分析如下: 為了深入理解訊息機制,先來做一個測試專案 在新建專案的Form1的程式碼中,加入方法: ?

Android AIDL實現程序通訊

        今天犯二了, 犯了個超級低階的錯誤, 真的是丟人丟大發了.         剛好順道反思下, 也對工作這幾年做一些簡單的總結. 不知道你們是不是和我一樣也總遇到各

linux 用命名管道實現程序通訊

什麼是命名管道 命名管道和匿名管道一樣適用於程序之間的通訊linux匿名管道詳解,但是使用範圍不同,匿名管道要求必須是親緣程序,而命名管道卻沒有這個限制,它可以用於同一臺機器主機上的任意程序間通訊。

android Aidl 實現程序通訊

1​,android 新建aidl 檔案 刪除void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString);這個方法沒用到 還需要實

第18天Service-Messager實現程序通訊

第18天Service-Messager實現程序間通訊 Messager 一.Messager介紹 二.Messager的原理 特點: 三 .使用步驟 服務端moudle:messager

Java使用管道實現程序通訊

1.程序通訊 大家都知道程序間通訊有三種常用方式: 1)管道 2)共享記憶體 3)socket baidu也有說8種方式的,其實基本都是這三種方式的進一步細化。 2.Java程序通訊 Java沒有共享記憶體機制,同時Java的管道也只能用於Java執行緒間的通訊。 下

Android Studio使用AIDL 實現程序通訊例項

參考:部落格:http://www.cnblogs.com/BeyondAnyTime/p/3204119.html, http://www.cnblogs.com/linlf03/p/3192025.html     視訊教程:http://www.imooc.com/l

Python 實現程序通訊(網路程式設計)

【網路程式設計】   1):網路程式設計是什麼意思,網路程式設計指的是不同機器之間通過網編相互發資訊,我們常用的“QQ”,“微信”,“郵箱” 都個網編程式設計的應用;   網編程式設計在技術上還有另一個叫法叫“程序間通訊”,程序間通訊這個名字能更好體現技術的內涵,說白了就是一個程序給另一個程序發   資訊;

Linux訊息佇列實現程序通訊

什麼是訊息佇列: 訊息佇列提供了從一個程序向另一個程序傳送一個有型別資料塊的方法。用這種方法可以避免命名管道的同步和阻塞問題。訊息佇列是基於訊息的,而管道是基於位元組流的,並且訊息佇列的讀取不一定是先入先出。 訊息佇列的操作: 訊息佇列的建立或者獲取: int msgg

Windows核心程式設計之郵槽實現程序通訊

    郵槽是Windows系統提供的一種單向通訊的機制。即程序中的一方只能寫入或讀取資料,而另一方則只能讀取或寫入資料。通過郵槽,使用者可以實現一對多或跨網路的程序之間的通訊。但是,郵槽能傳輸的資料

Android中Binder機制實現程序通訊

           基本上不管是何種開發都會涉及到程序間通訊的問題,即IPC,而安卓系統的IPC方式主要是Binder,先列舉幾種IPC的方式,對比Binder看看。       Linux裡