【问题标题】:C++ mmap of a set集合的 C++ mmap
【发布时间】:2012-12-01 04:01:49
【问题描述】:

我有一个使用 fork() 的 C++ 程序,但我需要能够在父进程及其子进程之间共享一个可以读写的对象。从我的在线阅读来看,似乎 mmap 是这样做的方法。这是我所拥有的:

enum messageType {New = 0, Old = 1, No_Message = 2};

typedef struct {
    enum messageType type;
    unsigned int senderID;
    char message[100];
} StoredMessageData;

struct StoredMessage {
    unsigned int recipientID;
    vector<StoredMessageData> messages;

    StoredMessage(const unsigned int& intRecipient = 0, const vector<StoredMessageData>& data = vector<StoredMessageData>())
    : recipientID(intRecipient), messages(data)
    {
        messages.reserve(10);
    }

    bool operator<(const StoredMessage& compareTo) const
    {
        return recipientID < compareTo.recipientID;
    }

    bool operator==(const StoredMessage& compareTo) const
    {
        return recipientID == compareTo.recipientID;
    }
};

然后在main中:

set<StoredMessage> * msgs;
msgs  = mmap(NULL, sizeof(set<StoredMessage>), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);

然后在 main 中我使用 fork()。

我的问题分为两部分:

1) 一个集合的大小是可变的,我已经知道在每个分叉的进程中,我希望能够添加一个 StoredMessage 并将一个 StoredMessageData 添加到 StoredMessage 中的向量。但是,我不确定 mmap 可以处理这个......它不只是为基础对象分配足够的空间吗?我可以让它分配足够的空间让我进行这些添加吗?

2) main 中的上述代码当前正在抛出错误:

错误:从 âvoid*â 到 âstd::set, std::allocator 的无效转换 >*â

有谁知道这意味着什么/如何解决它?

提前谢谢你!

【问题讨论】:

  • 我不想让人沮丧或任何事情,但如果你不能自己回答这些问题,你可能不应该这样做。实际上不,这行不通。
  • 如果它们实际上是简单的问题,我深表歉意;我通常不使用 C++ 编程。但是,为了学习,提出有用的答案而不是贬低的答案可能在未来更有帮助。
  • 我的意思是你甚至没有意识到这种方法的实际问题是什么。而且您显然没有掌握 C++ 基础知识。答案又是“这行不通”。
  • 我的意思是你上面的回答是错误的......他们让我不知道为什么这不起作用,我可能能够建设性地使用它来实际学习任何东西,也他们是否提供了我可能会研究的任何可能会更好的东西。正如我所说,我不是 C++ 程序员,也没有声称对 C++ 有任何深入的了解,显然,从我的问题的明显愚蠢来看,我没有。但是,我并没有从你那刻薄的 cmets 那里学到任何东西,也没有在使用 C++ 方面做得更好。
  • @GossamerShadow,请记住 std::set 不仅仅是 std::set 对象本身; std::set 在幕后为其树节点等分配了许多其他内存位。您必须使用placement new 和自定义std::allocator 来确保集合及其所有内部数据结构适合预分配共享内存段,以及处理同步。为什么不使用文件系统(set=directory, key=filename)?还是让父母管理集合,孩子通过管道向父母发送集合读/写命令?

标签: c++ multithreading set fork mmap


【解决方案1】:

STL 类 std::vector 和 std::set 使用 operator new() 分配内存。 运算符 new() 从进程堆中分配内存。 堆不在共享内存中,所以一个进程分配的任何东西都不能被另一个进程访问。

您有几个选择。首先是创建一个从共享内存分配的 std::allocator。

第二个(也是我的偏好)是不要在共享内存中使用任何使用指针的对象。 这几乎消除了 STL 中的任何内容。

您还需要一个互斥锁来控制对共享数据的访问,以便两个进程 不要破坏您的共享数据。

【讨论】:

  • 你在这里说的已经在上面的问题cmets中涵盖了,然后还有更多;请考虑为您的帖子添加更多详细信息、参考资料、相关示例等,以增加有形价值。您可能还想探索替代方案(同样,比 cmets 更详细。)
猜你喜欢
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 2016-03-02
  • 2014-06-04
  • 1970-01-01
相关资源
最近更新 更多