2013-08-29 91 views
3

我正在尋找關於在Windows上共享內存段中存儲少量數據(只有幾個字節)的建議和建議。使用Windows共享內存共享小數據

現在,無論何時映射共享內存,我們都會將映射大小舍入到最接近的4KB,這樣我們就可以得到多個映射的頁面。

mem_size = ((mem_size + 4095)/4096) * 4096; 

但是,我想映射足夠的內存來共享進程之間的命名整數。或者更具體地說,在進程之間有許多不同名稱的整數。大約一千個整數,所有名稱都不相同,每個整體都映射有一個或多個進程,這正是我所看到的。

我不想將4個字節四捨五入到4KB,因爲這將是一個巨大的浪費。在創建了一千多個這樣的內容之後,當我只需要一個時,我就會使用大約一千頁。

但我擔心只有4個字節創建一個命名的內存段的開銷。操作系統是否「合理」足以在可能的情況下試圖將不同的映射放入同一頁面? (我知道沒有保證)。或者這會很快吹滅?

我曾考慮映射一個巨大的內存塊,但仍然需要按名稱引用個別整數。在共享內存中維護一個哈希表似乎我只是在複製操作系統的工作。

是否有替代CreateFileMapping/OpenFileMappingMapViewOfFile技術,這將更適合在進程之間共享非常少量的數據?還是我擔心什麼都沒有?

+0

你說多少個整數(粗略)? –

+0

@JonathanPotter粗略的估計大概是1000,所有的名字都不一樣。每一個都將被一個或多個進程映射。 – Anthony

+0

如果您不想複製/實現您自己的散列系統,我可以想到的是使用'GlobalAddAtom()'爲每個名稱獲取一個原子,將一個數據塊作爲原子 - >索引的映射來維護,另一塊數據存儲實際數據。這並不理想,因爲它需要線性搜索原子圖來將原子轉換爲索引。 –

回答

4

你可以在8K做到這一點。第一個4k塊是整數名稱及其在第二個4k塊中的偏移的二進制表(或散列表)。添加新名稱時,您需要序列化,並在檢索名稱/偏移量時阻止該序列化。

在一個進程檢索到它的名字/偏移後,它可以直接進入第二個塊並避免任何序列化!這將是一個邏輯路徑,其時間超過90%(可能)。因此,您的代碼應該以最小的開銷非常有效地運行

第二個4k塊將持有1,000 int s(在窗口中!)。每個整數將不是影響其他人,所以這個設計是「線程安全」。但是,如果進程執行了很多操作(每個進程更新大約每隔1ms,因此兩個進程總是爭用寫入文件)更新到此公用文件,並且必須對整個文件進行序列化(而不是隱含的,因爲沒有兩個進程共享相同的整數名稱),當更新時,你可能最終會遇到一個瓶頸。

以下鏈接:http://msdn.microsoft.com/en-us/library/aa366801%28v=vs.85%29.aspx介紹瞭如何更新共享內存。如果每個進程都有自己的整數「slot」,那麼就不應該有任何爭用。

我不認爲名稱樹或哈希表是複製操作系統。

最後,這似乎是一箇中等技能的項目,應該相對容易維護!

+0

只要沒有兩個名字哈希到相同的值。 –

+0

@JonathanPotter,**不是** true。散列表將名稱放入桶或列表指針的頭部,然後按順序搜索完成匹配。散列表的要點是有一個O(k)散列,然後第二個O(n/nr_bins)搜索順序列表,這是n的一小部分。 – JackCColeman

+0

我知道什麼是散列表,但是你所描述的聽起來並不像它使用桶,而是依賴於表中名稱和索引之間的直接1:1關係。我不確定你能用4Kb做到這一點,但如果你可以 - 很好:) –

1

x86處理器上的共享內存段不能小於4096字節。共享內存由處理器上的mmu處理,該處理器組織4096字節大頁面中的所有內容。