如何在不存在数据损坏风险的情况下序列化对象?

时间:2016-04-15 12:56:55

标签: c++ named-pipes

我想序列化一个像这样的基本类:

class ProcessData
{
  public:
    ProcessData();
    ProcessData(int processNumber, int threadStatus);
    ~ProcessData();
    int getProcessNumber() const;
    void setProcessNumber(int processNumber);
    int getThreadStatus() const;
    void setThreadStatus(int threadStatus);
  private:
    int _processNumber;
    int _threadStatus;
};

并将其写入命名管道。 我使用命名管道,因为我需要我的子进程将数据发送到我的主进程。

我的主进程将读取此命名管道并返回我的对象​​。

问题是很多进程都可能写入命名管道,这可能会导致问题。 为了序列化这个课,我想我可以这样:

write(namePipeFileDesriptor, &processDataClass, sizeof(processDataClass)));

除了boost::serialization之外,您认为这可行吗?还是有其他选择?

2 个答案:

答案 0 :(得分:2)

我建议使用google::protobuf库进行序列化和反序列化。它高效快捷。

对于您的情况,您只需创建一个.proto文件

// File.proto
message ProcessData
{
  int32 _processNumber;
  int32 _threadStatus;
}

使用protoc编译器编译后,您将获得" File.pb.h"和" File.pb.cpp",您必须添加到您自己的项目中。就是这样。现在,您可以使用这些源文件中提供的各种方法简单地序列化和反序列化所需的数据。

另一个额外的好处是,相同的" File.proto"可以用于其他语言,如Go,Phython,Java,C#,...因为消息是以语言无关的方式[de]序列化的。

答案 1 :(得分:1)

只要读取器和编写器进程在同一台计算机上运行,​​编译为同一目标,具有相同的对齐规则,并且要发送的数据是POD(或可以视为POD),您可以管道数据就像你建议的那样,并避免使用序列化库。

现在,我猜你关注的是写/读操作的原子性,无论你使用什么序列化技术,考虑到几个编写器进程可以写入管道。

假设您的操作系统符合POSIX标准,只要发送的数据大小不超过管道缓冲区大小,您就可以将任何写操作视为原子操作(即:无数据交错)。

Standard州:

  

{PIPE_BUF}字节或更少字节的写请求不应与来自在同一管道上执行写操作的其他进程的数据交错。大于{PIPE_BUF}字节的写入可能在任意边界上交错数据,而其他进程的写入也是如此,无论文件状态标志的O_NONBLOCK标志是否已设置。

PIPE_BUF的值取决于操作系统,但应大于512字节。 (Linux操作系统为4096字节。)因此,对于小型数据,应该没有问题。