簡體   English   中英

在不序列化的情況下在共享內存中發送 POD 類型

[英]Sending a POD type in shared memory without serializing

我的項目中有兩個進程 P1 和 P2。 他們使用boost::interprocess::shared_memory來創建一個正常工作的共享內存段(同步沒有問題)。 我的用例包括從 P1 向 P2 發送一個 POD 類型( 一種可簡單復制的類型)。 假設 POD 類型如下所示:

struct Widget
{
    char val;
    int length;
}

我覺得這很容易,並提出了一種似乎對所有 POD 類型都通用的方法:

在共享內存中創建一個char buff[MAX_SIZE] 隨后做:

// P1
Rectangle R = {'a', 4};
memcpy(pointer_to_shared_memory, &R, sizeof(R));

// P2
Rectangle R;
memcpy(&R, pointer_to_shared_memory, sizeof(R));
// use R 

有什么問題,即使對象的模式沒有改變,編譯器在分別編譯 P1 和 P2 期間引入的默認填充會發生什么? 盡管 P1 和 P2 將在相似的條件下(構建標志等)以及在相同的系統、相同的 gcc 版本上編譯,但我仍然不能將填充要求留給 gcc,它會在兩個不同的場景中隨意執行。

例如,在這里,我希望 P1 和 P2 都將 Widget 表示為:

v---
llll

其中 v 是 char val,l 是長度(共 8 個字節)。 我的 pod 可能包含 uint8、unint16 等,它會隨着時間的推移變得復雜。 我有一種感覺,我不能依賴編譯器為兩個不同的進程修復內存中的相同填充,即使它們的模式在源代碼中是固定的。

有沒有辦法,如果模式在 P1 和 P2 中相同,我可以保證填充也將是一致的並且將由編譯器以一致的方式處理嗎? 我不想使用pragmapack預處理器,因為它們會限制我可以發送的 POD 類型。

flatbuffers這樣的序列化庫是否可以處理所有這些,我必須為此使用一個嗎? (我希望不會!我不想為 POD 類型引入序列化/反序列化對象的額外開銷)

我仍然不能將填充要求留給 gcc,它會在兩個不同的場景中隨意執行。

結構布局/填充量不是任意的,並且不會因編譯器的運行而不同。 如果是這樣,單獨的編譯將是不可能的,更不用說 IPC 了。 想象一下,如果 Widget 是在包含在兩個單獨文件中的標頭中定義的。 編譯器在編譯兩個不同文件之間改變填充是不行的。 如果填充/布局不一致,libc 中采用結構(例如 lstat)的任何函數都將毫無用處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM