QSharedMemory爲多線程和多進程提供了訪問共享內存段的功能。
但使用該類時,在不同的平臺上會有一點差異:
- Windows:QSharedMemory對象不擁有共享內存段。當擁有一個關聯在特定共享內存段上的QSharedMemory實例的線程或進程,在銷燬它們的QSharedMemory實例時,Windows內核會自動釋放共享內存段。
- Unix:QSharedMemory對象擁有共享內存段。當最後一個擁有關聯在特定共享內存段的QSharedMemory實例的線程或進程,通過銷燬QSharedMemory實例而從共享內存段detach時,Unix內核會釋放共享內存段。但是,如果最後一個線程或進程沒有運行QSharedMemory的析構函數就崩潰了,那麼共享內存段會持續存在。
- HP-UX:在一個進程內,只能有一個線程關聯到共享內存上,這意味着在該平臺上,QSharedMemory不能在同一個進程的多個線程間使用。
還有,當我們在從共享內存段中讀取或向其中寫入數據時,應該先使用lock()鎖定該共享內存段,並在訪問完成後,使用unlock()來解鎖。
QSharedMemory會在最後一個QSharedMemory實例從共享內存段detach()時,自動銷燬共享內存段。
下面,我們寫兩個應用程序來使用一下該類。
新建兩個控制檯程序,Shared1和Shared2。其中,Shared1會創建共享內存,並向其中寫入一個字符串;Shared2則從該共享內存段中讀出相應的內容。
Shared1代碼如下:
#include <QCoreApplication>
#include <QSharedMemory>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSharedMemory sm("SharedMem");
if(sm.isAttached())
{
sm.detach();//將該進程與共享內存段分離
}
if(!sm.create(100))
{
qDebug() << "Create Shared Memory Failed";
return 0;
}
qDebug() << "share memory size: " << sm.size();
if(!sm.lock())
{
qDebug() << "Can't lock the shared memory";
return 0;
}
const char* str = "hello, shared memory";
memcpy((char*)sm.data(), str, sm.size());
if(!sm.unlock())
{
qDebug() << "Can't unlock the shared memory";
return 0;
}
qDebug() << "Write to shared memory: " << str;
return a.exec();
}
#include <QCoreApplication>
#include <QSharedMemory>
#include <QDebug>
#include <QBuffer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSharedMemory sm("SharedMem");
if(!sm.attach())
{
qDebug() << "Attach Shared Memory Failed";
return 0;
}
if(!sm.lock())
{
qDebug() << "Can't lock the shared memory";
return 0;
}
QBuffer buf;
buf.open(QIODevice::WriteOnly);
buf.write((char*)sm.data());
buf.close();
if(!sm.unlock())
{
qDebug() << "Can't unlock the shared memory";
return 0;
}
qDebug() << "Load from shared memory: " << buf.data();
return a.exec();
}
同時啓動兩個程序,運行結果如下:說明,我們從共享內存中讀取到了我們寫入的信息。
並且,還有注意第一幅圖中,我們打印出的共享內存的大小。我們在使用create()函數創建共享內存時,明明指定的大小是100字節,但打印出的大小卻是4096字節,可見QSharedMemory類會將共享內存塊的大小舍入到系統內存頁面的大小,即4k。