简体   繁体   English

在不序列化的情况下在共享内存中发送 POD 类型

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

I have two processes P1 and P2 in my project.我的项目中有两个进程 P1 和 P2。 They use boost::interprocess::shared_memory to create a shared memory segment that is properly working (no problem with synchronization).他们使用boost::interprocess::shared_memory来创建一个正常工作的共享内存段(同步没有问题)。 My use-case consists of sending a POD type ( a trivially copyable type ) from P1 to P2.我的用例包括从 P1 向 P2 发送一个 POD 类型( 一种可简单复制的类型)。 Let's say the POD type looks like:假设 POD 类型如下所示:

struct Widget
{
    char val;
    int length;
}

I kind of thought that would be easy, and came up with an approach which seems generic for all POD types:我觉得这很容易,并提出了一种似乎对所有 POD 类型都通用的方法:

Create a char buff[MAX_SIZE] in shared memory.在共享内存中创建一个char buff[MAX_SIZE] Subsequently do:随后做:

// 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 

What bugs me, even if the schema of the object doesn't change, what happens to the default padding that compiler introduces during the compilation of P1 and P2 separately?有什么问题,即使对象的模式没有改变,编译器在分别编译 P1 和 P2 期间引入的默认填充会发生什么? Although P1 and P2 would be compiled under similar conditions (build flags etc), as well on the same systems, same gcc versions, I still can't leave the padding requirements to gcc, which it would perform at will on two separate scenarios.尽管 P1 和 P2 将在相似的条件下(构建标志等)以及在相同的系统、相同的 gcc 版本上编译,但我仍然不能将填充要求留给 gcc,它会在两个不同的场景中随意执行。

For instance, here, I am expecting both P1 and P2 to have a representation of Widget as:例如,在这里,我希望 P1 和 P2 都将 Widget 表示为:

v---
llll

where v is char val, and l is length (a total 8 bytes).其中 v 是 char val,l 是长度(共 8 个字节)。 My pod may contain uint8, unint16 etc, and it will grow complex overtime.我的 pod 可能包含 uint8、unint16 等,它会随着时间的推移变得复杂。 I have a feeling I can't rely on compiler to fix the same padding in memory for two different processes, even though their schema is fixed in source code.我有一种感觉,我不能依赖编译器为两个不同的进程修复内存中的相同填充,即使它们的模式在源代码中是固定的。

Is there a way, can I guarantee that padding will also be consistent and will be taken care of by the compiler in consistent manner, if the schema is the same in both P1 and P2?有没有办法,如果模式在 P1 和 P2 中相同,我可以保证填充也将是一致的并且将由编译器以一致的方式处理吗? I don't want to use pragma or pack preprocessors, since they will limit the type of PODs that I could send over.我不想使用pragmapack预处理器,因为它们会限制我可以发送的 POD 类型。

Does a serialization library like flatbuffers take care of all of this, and I must use one for this?flatbuffers这样的序列化库是否可以处理所有这些,我必须为此使用一个吗? (I hope not! I don't want to introduce the extra overhead of serialzing/deserializing objects for a POD type) (我希望不会!我不想为 POD 类型引入序列化/反序列化对象的额外开销)

I still can't leave the padding requirements to gcc, which it would perform at will on two separate scenarios.我仍然不能将填充要求留给 gcc,它会在两个不同的场景中随意执行。

The struct layout/amount of padding is not arbitrary and will not differ from run to run of the compiler.结构布局/填充量不是任意的,并且不会因编译器的运行而不同。 If it did, separate compilation would be impossible, never mind IPC.如果是这样,单独的编译将是不可能的,更不用说 IPC 了。 Imagine if Widget was defined in a header included in two separate files.想象一下,如果 Widget 是在包含在两个单独文件中的标头中定义的。 It would not be ok for the compiler to vary the padding between compiling the two different files.编译器在编译两个不同文件之间改变填充是不行的。 Any function in libc that took a struct (eg lstat) would be useless if padding/layout wasn't consistent.如果填充/布局不一致,libc 中采用结构(例如 lstat)的任何函数都将毫无用处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM