1. 程式人生 > >QT之QSharedMemory 詳解 程序間通訊

QT之QSharedMemory 詳解 程序間通訊

QSharedMemory的幾個重要介面:
setKey(),這是標記共享記憶體的一個識別符號,
在整個作業系統的共享記憶體中,用這個key去標識它,唯一標識。

create(),建立共享記憶體,向os申請記憶體空間,
如果不建立,呼叫attach()會失敗,
在create()的時候,需要制定共享記憶體的大小,即位元組數,
跟windows的CreateFileMapping()一樣,都是需要在create()的時候指定,而且大小是固定的,

從共享記憶體讀取資料的時候,必須要先繫結,寫入資料不需要attach(),
attach()函式,在workstation.exe程序中,呼叫該共享記憶體的attach()函式,
注意是,將該exe繫結到該共享記憶體中,
如果要讀取某個共享記憶體,必須要想將exe繫結到共享記憶體中,只有繫結成功,才能讀取,

bool QSharedMemory::detach ()
一定要注意這個函式,系統會自動釋放該共享記憶體,導致其data()返回為空,
detach()後,雖然該塊共享記憶體的地址為null,但是它的key還是存在的,因此,可以繼續呼叫create(),重新申請記憶體,然後就可以繼續使用了。

詳細使用過程:
向共享記憶體中提供資料的一方:

寫入資料的順序,最後是先呼叫一次detach(),然後呼叫create()重新申請記憶體。此時detach()實際上是清除共享記憶體中資料的作用,
1,定義QSharedMemory shareMemory,並設定標誌名shareMemory.setKey();//告訴os,我要使用這塊memory,
2,將共享記憶體與主程序分離 shareMemory.detach();//如果是當前exe是最後一個使用該memory的程序,那麼detach()後,該共享記憶體的記憶體地址就被os釋放了,即data()返回null。
但是key還在,還可以使用後面的create()再重新向os申請記憶體,
3,建立共享記憶體 shareMemory.create();//向os申請記憶體
4,將共享記憶體上鎖shareMemory.lock();
5,將程序中要共享的資料拷貝到共享記憶體中;
6,將共享記憶體解鎖shareMemory.unlock();
寫完後,堅決不能呼叫detach(),如果呼叫detach(),那麼共享記憶體的記憶體會被os釋放掉,寫入的位元組就被刪除,

從共享記憶體中取資料的一方:(讀取資料,必須呼叫attach())
1,定義QSharedMemory shareMemory,並設定共享記憶體的標誌名shareMemory.setKey()注意設定的要與提供記憶體共享的一方要一樣。
2,將共享記憶體上鎖shareMemory.lock();
3,將共享記憶體與主程序繫結shareMemory.attach(),使該程序可以訪問共享記憶體的資料;
4,從共享記憶體中取資料;
5,使用完後將共享記憶體解鎖shareMemory.unlock(),另外將共享記憶體與該程序分離shareMemory.detach();

實現一個共享記憶體資料互動的執行緒類,執行緒的run函式如下:
void run()
{
    QSharedMemory   sharedMem;
    sharedMem.setKey(m_sharedMemName);
    bool res = sharedMem.attach(QSharedMemory::ReadOnly);
    if (!res) {
        return;
    }

    while (!m_requestStop) {
        sharedMem.lock();
        char *memData = (char*)sharedMem.data();
        memcpy((void*)&vi, memData, headerSize);

        sharedMem.unlock();
        //進行業務資料處理
        //to do...

        sharedMem.unlock();
    }

    sharedMem.detach();
}