2011-12-12 74 views
0

共享內存給我一個很難的時間,GDB沒有太大的幫助。我已經分配了32KB共享內存,並且我使用shmat將其轉換爲指向包含A)a bool和B)包含一個std::string,3個ints和一個bool的對象隊列以及各種方法的指針struct 。 (我不知道這個俄羅斯套娃結構是如何做到的,但這是我知道的唯一方法。使用消息隊列不是一種選擇,我需要使用多個進程。)隊列共享內存代理

將一個對象推到隊列上工作,但是當我嘗試推一秒時,程序凍結。沒有錯誤信息,沒有任何東西。這是什麼造成的?我懷疑這是缺乏記憶,但如果是這樣,我需要多少?

編輯:如果我不清楚 - 隊列中的對象是一個類與五個數據成員描述。

編輯2:我改變了隊列條目的類別,以便它不使用std::string。 (令人尷尬的是,我能夠用原語表示數據。)該程序在第二次push()時仍然凍結。

編輯3:我嘗試的第一個push()後會立即調用同一個隊列front(),並凍結的程序了。檢查 以外的值但是,該隊列工作正常,所以它必須在隊列本身出現問題。

EDIT 4:作爲一個實驗,我添加了一個std::queue<int>struct我使用的共享存儲器。它表現出相同的行爲 - push()曾經工作過,然後front()凍結。所以對於我用於隊列項目的類也不是問題。

This問題建議我不可能用std::queue來解決這個問題。是這樣嗎?我應該使用boost嗎? (在我的情況,我在父進程執行shmget()shmat(),並試圖讓兩個子進程進行通信,所以它的略有不同。)

編輯5:當它調用front()其他子進程也凍結。信號量確保在第一次調用push()之後發生這種情況。

+0

其中是分配了「std :: string」的內存?我打賭兩個便士,那就是你的問題所在。 – Nim

+0

我們可以看到再現症狀的最小,完整的代碼嗎?我們不知道如何在共享內存上放置'std :: queue',如何使用信號燈等等。 – pilcrow

回答

5

std::string對象放入共享內存段不能可能工作。

它應該適用於單個進程,但只要嘗試從第二個進程訪問它,就會得到垃圾:字符串將包含指向堆分配數據的指針,並且該指針爲只有在分配它的過程中有效。

我不知道你的程序爲什麼會死機,但它完全是毫無意義的想都沒想。

1

正如我在我的評論中所說的,您的問題源於嘗試使用內部需要堆分配的對象,該對象應該是自包含的(即不需要進一步動態分配的內存)。

我會調整你的設置,和的std :: string更改爲某個固定大小的字符數組,像

// this structure fits nicely into a typical cache line 
struct Message 
{ 
    boost::array<char, 48> some_string; 
    int a, b, c; 
    bool c; 
}; 

現在,當您需要發佈隊列的東西,字符串的內容複製到some_string。當然,你應該適當地調整字符串(並且boost::array可能不是最好的 - 理想情況下你也想要一些長度信息),但你明白了...

+0

猜測我明白內存分配的工作原理比我想象的還要好。 ^^;它確實看起來像一個_impartial_分析表明避免_heap_會使我更少_misère-y_。 (你怎麼估計一個對象將佔用的空間量,雖然?) –

+0

使用'sizeof(object)'也許吧? –

+0

在編輯註釋後已過了幾分鐘,我想到了這一點。 -_-我仍然無法讓隊列正常工作 - std :: queue'基本上是工作的錯誤工具嗎? –