我正在创建服务器,其中有一个处理客户端的类,一个处理服务器的类以及另一个将每个新客户端显示到列表框中的类。我想要做的并且大部分工作的方式是,我使用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);
这是我的Server类初始化的样子:
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变量也可以按我的意愿工作。显然,我的类(class)和代码还有很多。我只是想确切说明相关内容。
还应注意,使用clang++编译时不会出现任何警告或错误。除了每次运行此命令外,我都会收到一个zsh: segmentation fault,这意味着它正在尝试读取和/或写入非法内存。有什么方法可以做我想要的吗?

最佳答案

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一个分配器,该分配器仅分配该共享内存的块,以便其他进程可以理解放置在共享内存中的指针。
这可能比它值得的麻烦更多,并且您可能最好重新考虑设计。

关于c++ - 是否可以在C++中将列表分配到共享内存中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/65099645/

10-11 15:54