Qt QSharedMemory共享記憶體的使用
可用於程序間通訊。
建立物件:利用QSharedMemory類建立例項物件時,必須為該共享記憶體指定關鍵字(即為該共享記憶體起一個名字)。只有當共享記憶體被設定了關鍵字之後,才可以執行建立create()、關聯attach()等操作。為共享記憶體指定關鍵字有兩種方法:
SharedMemory* sharememory;
sharememory = newQSharedMemory("QSharedMemoryExample");
還有一種方式:
SharedMemory* sharememory; sharememory = new QSharedMemory(); sharememory->setKey("QSharedMemoryExample ");
bool QSharedMemory::create ( int size, AccessMode mode =ReadWrite )
為QSharedMemory類例項物件建立一個空間大小為size的共享記憶體,該記憶體空間預設的訪問方式為可讀可寫。共享記憶體建立成功返回true,否則返回false。QSharedMemory類定義一個列舉類變數AccessMode,指定了兩種共享記憶體的訪問方式:
QSharedMemory::ReadOnly 只讀方式訪問共享記憶體
QSharedMemory::ReadWrite 讀寫方式訪問共享記憶體
注意,create會自動attach程序。
3、關聯共享記憶體
bool QSharedMemory::attach ( AccessMode mode =ReadWrite )
將以關鍵字key命名的共享記憶體和當前程式進行關聯,共享記憶體預設的訪問方式為可讀可寫。如果程式和共享記憶體關聯成功,返回true,否則返回false。
4、分離共享記憶體
bool QSharedMemory::detach ()
解除共享記憶體和程式的關聯,即呼叫該函式後,程式不可以再訪問共享記憶體。如果該共享記憶體被多個程式例項所關聯,當最後一個程式例項和共享記憶體解除關聯後,該共享記憶體將由作業系統自動釋放掉。分離操作成功,返回true。如果返回false,通常意味著該共享記憶體和程式分離失敗,或者其他程式當前正在訪問該共享記憶體,分離操作執行失敗。
5、判斷共享記憶體的關聯狀態
bool QSharedMemory::isAttached ()const
該函式用來判斷程式(呼叫該函式的程式)是否和共享記憶體進行關聯,是返回true,否返回false。
6、設定/獲取共享記憶體的關鍵字
QString QSharedMemory::key ()const //獲取共享記憶體關鍵字
Qt應用程式通過關鍵字來辨識共享記憶體。key ()函式用來獲取共享記憶體的關鍵字,如果沒有指定例項物件的關鍵字,或者共享記憶體的關鍵字是由nativeKey ()函式指定的話,則返回空。
void QSharedMemory::setKey (const QString & key ) //設定共享記憶體關鍵字
setKey ()函式用來為共享記憶體段設定關鍵字(為共享記憶體命名),如果引數key的值和建構函式或者之前指定的關鍵字相同的話,則該函式將不做任何操作,直接返回。
7、鎖定/解鎖共享記憶體
bool QSharedMemory::lock () //鎖定共享記憶體
如果共享記憶體資源當前處於釋放狀態,程序呼叫該函式將共享記憶體中的資源鎖定,並返回true。其他程序將不能訪問該共享記憶體。如果共享記憶體被其他程序佔用時,則該函式會一直處於阻塞狀態,直到其他程序使用完畢,釋放共享記憶體資源。
bool QSharedMemory::unlock () //解鎖共享記憶體
如果共享記憶體資源被當前程序所佔有,呼叫該函式將解鎖該共享資源,並返回true。如果當前程序沒有佔用該資源,或者共享記憶體被其他程序訪問,則不做任何操作並返回false。
為了保證共享記憶體中資料的完整性,當一個程序在讀寫共享記憶體的時候,其他程序不允許對該共享區域進行訪問。QSharedMemory類提供了lock()函式和unlock()函式來實現這一共享記憶體訪問機制。某一程式對共享記憶體進行讀寫操作之前,需要呼叫lock()函式鎖定該共享記憶體,之後獨享共享記憶體中的資料,並對資料進行讀寫等操作。共享記憶體訪問完畢,呼叫unlock()函式,釋放共享記憶體的使用許可權。
8、錯誤原因
SharedMemoryError QSharedMemory::error ()const
當共享記憶體出錯時,呼叫該函式顯示相應的錯誤程式碼。
QString QSharedMemory::errorString ()const
當共享記憶體出錯時,呼叫該函式,以文字形式顯示錯誤原因。
9、獲取共享記憶體的地址
const void *QSharedMemory::constData ()const
void * QSharedMemory::data ()
const void *QSharedMemory::data ()const //過載函式
程式關聯共享記憶體的前提下,呼叫該函式返回共享記憶體中資料的起始地址。如果沒有關聯共享記憶體,則返回0。
10、獲取共享記憶體的大小
int QSharedMemory::size ()const
呼叫該函式將返回程式所關聯的共享記憶體的大小(位元組)。如果沒有關聯的共享記憶體,則返回0。
#include "dialog.h"
#include "ui_dialog.h"
#include <QFileDialog>
#include <QBuffer>
#include <QDebug>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
sharedMemory.setKey("liuzhichao");
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::loadFromFile()
{
if (sharedMemory.isAttached())
detach();
ui->label->setText(tr("選擇一個圖片檔案!"));
QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(),
tr("Images (*.png *.jpg)"));
QImage image;
if (!image.load(fileName)) {
ui->label->setText(tr("選擇的檔案不是圖片,請選擇圖片檔案!"));
return;
}
//ui->label->setPixmap(QPixmap::fromImage(image));
// 將圖片載入到共享記憶體
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QDataStream out(&buffer);
out << image;
int size = buffer.size();
if (!sharedMemory.create(size)) {
ui->label->setText(tr("無法建立共享記憶體段!"));
return;
}
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), size));
sharedMemory.unlock();
}
void Dialog::loadFromMemory()
{
// if (!sharedMemory.attach()) {
// ui->label->setText(tr("無法連線到共享記憶體段,\n"
// "請先載入一張圖片!"));
// return;
// }
if(!sharedMemory.isAttached())
sharedMemory.attach();
QBuffer buffer;
QDataStream in(&buffer);
QImage image;
sharedMemory.lock();
buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
buffer.open(QBuffer::ReadOnly);
in >> image;
sharedMemory.unlock();
sharedMemory.detach();
ui->label->setPixmap(QPixmap::fromImage(image));
}
void Dialog::detach()
{
if (!sharedMemory.detach())
ui->label->setText(tr("無法從共享記憶體中分離!"));
}
void Dialog::on_loadFromFileButton_clicked()
{
loadFromFile();
}
void Dialog::on_loadFromSharedMemoryButton_clicked()
{
loadFromMemory();
}