在Linux上的进程间共享数据

问题描述:

在我的应用程序中,我有一个分叉子进程,说child1,并且这个子进程在磁盘上写入一个巨大的二进制文件并退出。然后,父进程分离出另一个子进程child2,该进程读入这个大文件以进行进一步处理。在Linux上的进程间共享数据

该文件转储和重新加载正在使我的应用程序变得缓慢,我正在考虑可能的完全避免磁盘I/O的方法 。我已经确定的可能的方法是ram-disk或tmpfs。 我可以以某种方式在我的应用程序中实现ram-disk或tmpfs吗?或者有没有其他的方式可以完全避免磁盘I/O,并且可靠地跨进程发送数据。

+0

只是为了将更多的东西放在正确的角度看,父进程实际上分出了3-4个子进程写入磁盘,然后这些文件被后续的子进程读入。所有这些子进程不会同时存在,并在将数据写入磁盘后退出。 – user900563

+0

由于涉及到很多流程,我认为设置管道可能会变得过于复杂和脆弱。相反,如果我可以构建一个封装的API来模拟磁盘以满足我需要的几件事,那就太酷了! – user900563

+0

为什么分叉?使用线程并将该文件保存在内存中。 – Matt

如果两个子进程不同时运行,管道或套接字将无法工作 - 它们的缓冲区对于“巨大的二进制文件”来说太小了,第一个进程将阻塞等待任何读取数据。

在这种情况下,您需要某种共享内存。您可以使用SysV IPC共享内存API,POSIX共享内存API(在最近的Linux上内部使用tmpfs)或直接在tmpfs上使用文件(通常挂载在/ dev/shm,有时在/ tmp上)。

+0

是的,子进程不会同时运行,但父进程处于活动状态直到最后一个子进程退出。我一直在考虑直接在tmpfs文件系统上使用文件,但不知道如何在程序中实现它们。任何指针? – user900563

生成两个进程,让他们通过套接字传输数据。 TCP最容易入门,但如果您想提高效率,请使用Unix Domain Sockets。这假定您不关心正在写入磁盘本身的数据。

+0

实际上2个子进程并不是同时存在的。第一个完成工作,转储文件并退出,在此之后,下一个孩子分叉,加载这个文件并完成其余的处理。我可以在parent-child1和parent-child2之间建立一个套接字吗? – user900563

+0

让他们同时跑步怎么样?它可能会大大减少总运行时间,作为一项副作用。 –

您可以使用管道在进程之间传递数据。 Here是一个很好的概要和示例实现。

A named pipe正是你想要的。您可以将数据写入它并从中读取数据,就像它是一个文件一样,但不需要将其存储在磁盘上。

+0

为什么命名管道,当进程是从一个进程派生出来的,并且可以直接共享文件描述符? –

+0

@Jacek这是一个很好的观点;你是对的。 –

您可以使用管道和套接字,并利用Linux内核的sendfile()splice()功能(它们可以避免数据复制)。

分叉,然后所有的孩子都能叉后使用之前创建一个匿名的共享内存区域:

char *shared = mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); 

要知道,共享内存时,你需要一些同步机制。实现这一点的一种方法是在共享内存区域内放置一个互斥锁或信号量。

如您案第一个孩子的过程child1在退出的child2到来之前存在这样的socket通信,或者使用未命名管道不会帮助,

但共享内存将做的工作: 创建共享内存段在child1中具有读取所有权限的权限并在该共享内存中执行文件转储任务 在child2中,将共享内存段附加到当前进程空间并读取转储的数据。

+0

欢迎来到SO。请解释如何解决问题并给出一些例子。你可以阅读这个:http://*.com/help/how-to-answer – Sebi