首页 > 解决方案 > 是否可以在 C++ 中将列表分配到共享内存中?

问题描述

我正在创建一个服务器,其中有一个处理客户端的类,一个处理服务器的类,以及另一个将每个新客户端显示到列表框中的类。我想要这样做并且主要工作的方式是,我让服务器在使用 fork 的子进程上运行,而列表框在父进程上运行。我希望能够拥有一个包含不同客户端类的共享列表。在 python 中,它会用multiprocessing manager. 我一直找不到类似的东西。我目前尝试这样做的方式是使用mmap. 到目前为止,这基本上是我编写代码的方式:

我的相关头文件:

#include <list>
#include <sys/mman.h>

//creating the list
//the name of the client class is called ClientHolder
size_t pagesize = getpagesize();
std::list<ClientHolder> *Clients = static_cast<std::list<ClientHolder>*>(mmap(NULL, (pagesize*(1 << 20)),
                PROT_READ | PROT_WRITE,
                MAP_SHARED | MAP_ANONYMOUS, 0, 0));
//then it is passed into the server class as such:
Server newServer(*Clients);
//then initialized in my listbox class as well:
ListboxHandler newListboxHandler(listbox, *Clients);

这是我的服务器类初始化的样子:

class Server{
    bool running=false;
    char *ip;
    int Port;
    std::list<ClientHolder> *Clients;
    size_t pagesize = getpagesize();
    int *quit_call = static_cast<int*>(mmap(NULL, (pagesize*(1 << 20)),
                PROT_READ | PROT_WRITE,
                MAP_SHARED | MAP_ANONYMOUS, 0, 0));
    public:
        Server(std::list<ClientHolder> Clients){Clients = Clients;};

此外,quit_call 变量可以按我的意愿工作。显然,我的课程和代码还有很多。我只是想准确地展示什么是相关的。

还应该注意的是,使用 clang++ 编译时不会出现任何警告或错误。除了每次我运行它时,我都会得到一个zsh: segmentation fault,这意味着它正在尝试读取和或写入非法内存。有没有办法做我想做的事?

标签: c++forkmmap

解决方案


std::list<ClientHolder> *Clients = static_cast<std::list<ClientHolder>*>(mmap(NULL, (pagesize*(1 << 20)),
            PROT_READ | PROT_WRITE,
            MAP_SHARED | MAP_ANONYMOUS, 0, 0));

这行不通。该类std::list分配内存并存储指针。这些指针在另一个进程中将无效。您不能以std::list这种方式共享实例,因为每个进程都会将指向其自己内存空间的指针写入std::list共享内存中的实例,而另一个进程在尝试取消引用它们时会崩溃。

您将需要分配更多的共享内存,足以容纳您想要共享的所有内容。而且您需要提供std::list一个分配器,它只分配该共享内存的块,以便其他进程能够理解放置在共享内存中的指针。

这可能比它的价值更麻烦,你可能会更好地重新考虑设计。


推荐阅读