在Linux x86_64上使用单线程C++进行多处理

Multi-processing with singletons C++ on Linux x86_64

本文关键字:C++ 单线程 处理 x86 Linux      更新时间:2023-10-16

对于下面的问题,我正在寻找一个基于"纯"C/C++基础的答案,所以我希望得到一个非Boost的答案。谢谢

我有一个应用程序(例如,电信基础设施服务器),当启动时,它将在Linux环境中生成几个进程(一个用于日志记录,一个用于定时器管理,一个用来协议消息传递,一个用作消息处理等)。它在Gentoo上的x86_64环境中。问题是,我需要一个能够从所有进程访问的singleton。

这与Linux上使用POSIX线程的多线程不同,因为所有POSIX线程都使用相同的地址空间,但当使用fork()函数调用生成的多个进程时,情况并非如此。当使用相同的地址空间时,singleton在所有线程中都是相同的地址,问题就迎刃而解了(使用众所周知的保护措施,这对SO上的每个人来说都是老生常谈)。我确实喜欢通过fork()生成的多个进程为我提供的保护。

回到我的问题,我觉得正确的方法是在共享内存中创建singleton,然后将共享内存的句柄传递给调用任务。

我想象如下(SomeSingleton.h):

#include <unistd.h>
#... <usual includes>
#include "SomeGiantObject.h"
int size = 8192; // Enough to contain the SomeSingleton object
int shm_fd = shm_open ("/some_singleton_shm", O_CREAT | O_EXCL | O_RDWR, 0666);
ftruncate (shm_fd, size);
sharedMemoryLocationForSomeSingleton = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
class SomeSingleton
{
   public:
     SomeSingleton* getInstance ()
     {
        return reinterpret_cast<SomeSingleton*>sharedMemoryLocationForSomeSingleton;
     }
   private:
     SomeSingleton();
     /*
        Whole bunch of attributes that is shared across processes.
        These attributes also should be in shared memory.
        e.g., in the following
        SomeGiantObject* obj;
        obj should also be in shared memory.
     */
};

getInstance()方法返回SomeSingleton对象的共享内存位置。

我的问题如下:

  1. 这是处理问题的合法方式吗?SO上的人以前是如何处理这个问题的
  2. 为了让上面的代码发挥作用,我设想了一个全局声明(定义为静态),它指向类声明之前所示的共享内存
  3. 最后,但并非最不重要的是,我知道在Linux上,创建线程与进程的开销"相对相似",但我想知道为什么在SO上没有太多关于多处理的讨论(不过,多线程的大量负载!)。这里连标签都没有!多处理(使用fork())是否在C++编码社区中失去了青睐?对此有任何见解也将不胜感激。此外,我可以请求声誉>1500的人创建一个标签"多处理?"谢谢

如果在分叉之前创建共享内存区域,那么它将被映射到所有对等中的同一地址。

您还可以使用自定义分配器将包含的对象放置在共享区域中。这可能也应该在分叉之前完成,但要小心析构函数调用的重复(例如刷新缓冲区的析构函数是可以的,但任何使对象不可用的东西都应该跳过,只需泄漏,并在所有进程关闭共享内存句柄后让操作系统回收内存)。