Linux,与fork()中的另一个程序共享一个缓冲区

时间:2013-05-04 15:15:40

标签: c++ c linux posix shared-memory

我有一个客户端/服务器模型,其中每个客户端都可以向服务器发送任务 - 这称为任务请求。

这是我追求的简单分布式计算库的基础。

换句话说,如果某个普通应用程序处理一个独立元素数组,那么在数据并行模型中,每个处理器都被分配来处理数组的某些部分。为了支持数据并行计算,核心库应该将任务分成几部分,将任务数据传输到特定CPU的本地内存,在该CPU上运行任务,将结果传回给调用者,并提供从调用者请求一些全局数据的能力。

Data Paraller Diagram

  • 任务二进制(std :: vector uint8_t)和 Payload (std :: vector uint8_t)。
  • 二进制只是一个已编译的任务/应用程序。
  • Payload 是序列化为uint8_t的可选数据。

如此简单:

class CGridTask
{

    public:
        ...

        bool        Run             ();    

    private:
        std::vector<uint8_t>        m_vBinary;
        std::vector<uint8_t>        m_vPayload;
        uint32_t                    m_uiUniqueId;

        ...
}

伪图显示了它的工作原理:

[CLIENT1]---[SEND TASK with PAYLOAD: integer value = 10]-->[SERVER]

[SERVER]-->[RUN TASK with PAYLOAD]

[TASK, start]

[TASK, calculate...]
[TASK, calculate...]
[TASK, calculate...]
[TASK, integer value = 10 + some new value]

[TASK, return]

[SERVER]-->[SEND TASK to CLIENT1]

好的,所以当服务器调用时:

pGridTask->Run();

以下是应该发生的事情:

bool CGridTask::Run()
{
    // Dump the binary to a temporary file
    Dump(m_vBinary);

    // Chmod +x
    system("chmod +x " + strTempopraryBinaryName);

    // Run the binary and pass m_vPayload
    ...how can i do this?...

    // Return true if binary executed
    return true;
}

这里唯一的问题是与执行的二进制文件共享m_vPayload ... 我该怎么做?

非常感谢您对此的任何意见!

4 个答案:

答案 0 :(得分:3)

假设您想要修改内存以便“主”进程可以看到它,您将需要设置共享内存或内存映射文件的区域。作为进程的一部分分配的任何内存将在新进程写入时复制,因此不会“共享”。

答案 1 :(得分:1)

我不推荐它..但这样你可以“分享一切”

不要将fork()我们clone()与以下标志一起使用:CLONE_VM

  

CLONE_VM(自Linux 2.0起)

     

如果设置了CLONE_VM,则调用进程和子进程在同一内存空间中运行。特别是,由执行的内存写入   调用进程或子进程也可以在   其他过程。此外,执行任何内存映射或取消映射   用mmap(2)或munmap(2)由子或调用进程也会影响   另一个过程。

     

如果未设置CLONE_VM,则子进程在clone()时在调用进程的内存空间的单独副本中运行。   内存写入或文件映射/取消映射由其中一个执行   进程不会影响另一个进程,就像fork(2)一样。

http://linux.die.net/man/2/clone

的更多信息

但我相信你会遇到这个问题..动态分配的内存会泄漏..和co。

真正的解决方案是为有效负载设置mmap ..

答案 2 :(得分:1)

作为其他解决方案的替代方案,并且根据您的子流程的结构,您还可以通过管道(通常的pipe/fork/dup2/exec模式)与您的子流程进行通信。

确实性能比共享内存差,但整个架构更灵活,你的各种程序耦合得更少:从孩子的角度来看,它从stdin获取数据并输出结果stdout使其可以在其他上下文中轻松重用(这也使得在任务服务器的上下文中重用“普通”交互式程序非常容易,而无需先调整它们。)

答案 3 :(得分:1)

除了其他答案之外,您还可以考虑使用MPI消息传递接口标准,它有多个实现,包括Open MPI

当然,MPI不是共享内存模型,但它似乎与“发送数据部分”的高级软件架构很接近。

MPI非常普遍,一些高端铁制供应商(即百万欧元超级计算机)提供自己的硬件辅助MPI实现。

你也可以使用Posix共享内存,即shm_open(3)和朋友。见shm_overview(7)。然后你可能想与Posix信号量同步。请先查看sem_overview(7)

mmap(2)也可用于共享内存(MAP_SHARED标志)。

分享内存是不够的。您需要一些同步工具(告诉共享数据“已准备就绪”....)。

也许你可以考虑Pthreads。阅读一个好的Pthread tutorial(也是最近的C++2011标准提供线程)。

阅读Advanced Linux Programming以概述Linux下的许多IPC可能性。作为Siyam suggested,通常pipeforkdup2exec(和poll(2)用于输入和输出多路复用)值得考虑。