我正在使用Python多处理为每个进程生成一个临时输出文件。它们的大小可以是几GB,我可以制作几十个。这些临时文件需要合并以形成所需的输出,这是证明是瓶颈(和并行杀手)的步骤。是否有一个Linux工具可以通过修改文件系统元数据而不是实际复制内容来创建连接文件?只要它适用于我可以接受的任何Linux系统。但是文件系统特定的解决方案不会有太大帮助。
我不是OS或CS训练的,但理论上似乎应该可以创建一个新的inode并从我想要复制的文件的inode复制inode指针结构,然后取消链接那些inode。是否有任何实用程序可以做到这一点?考虑到经过深思熟虑的unix实用程序的过多,我完全可以预料到它,但找不到任何东西。因此我的问题是关于SO的。文件系统位于块设备上,实际上是硬盘,以防这些信息很重要。我没有信心自己编写这个,因为我以前从未做过任何系统级编程,所以任何指针(对C / Python代码的反转)都会非常有帮助。
答案 0 :(得分:14)
即使有这样的工具,这只能在除了最后一个文件之外的文件中有效 保证其大小是文件系统块的倍数 大小
如果您控制数据写入临时文件的方式,并且知道 每个人有多大,你可以改为做以下
在开始多处理之前,创建最终输出文件并增长
它到最后的大小
fseek()
荷兰国际集团
到最后,这将创造一个
sparse file
开始多处理,将每个进程FD和偏移量交给它 文件的特定片段。
这样,进程将协同填充单个输出文件, 不需要将它们放在一起。
修改强>
如果无法预测单个文件的大小,而是消费者的 最终文件可以使用顺序(而不是随机访问)输入,您可以 在stdin
上向消费者提供cat tmpfile1 .. tmpfileN
cat tmpfile1 ... tmpfileN | consumer
或通过命名管道(使用bash的Process Substitution):
consumer <(cat tmpfile1 ... tmpfileN)
答案 1 :(得分:5)
您表示您事先并不知道每个临时文件的大小。考虑到这一点,我认为最好的办法是编写一个FUSE文件系统,将块作为单个大文件呈现,同时将它们保存为底层文件系统中的单个文件。
在此解决方案中,您的生产和使用应用程序保持不变。制作人写出了一堆文件,FUSE图层将显示为作为单个文件。然后将此虚拟文件呈现给消费者。
FUSE对一堆语言including Python具有绑定。如果你看一些例子here或here(这些是针对不同的绑定),这需要很少的代码。
答案 2 :(得分:2)
我不这么认为,inode可能是对齐的,所以只有你可以在一个文件的页脚和另一个文件的标题之间留下一些零(或未知的字节)时才有可能。
我建议重新设计分析工具以支持从多个文件中获取,而不是连接这些文件。以日志文件为例,许多日志分析器支持每天读取日志文件。
修改的
@san:正如您所说的使用中的代码无法控制,您可以使用命名管道动态连接单独的文件:
$ mkfifo /tmp/cat
$ cat file1 file2 ... >/tmp/cat &
$ user_program /tmp/cat
...
$ rm /tmp/cat
答案 3 :(得分:2)
4个文件; xaa,xab,xac,xad是bash中的快速连接(以root身份):
losetup -v -f xaa; losetup -v -f xab; losetup -v -f xac; losetup -v -f xad
(假设loop0,loop1,loop2,loop3是新设备文件的名称。)
将http://pastebin.com/PtEDQH7G放入“join_us”脚本文件中。然后你可以像这样使用它:
./join_us /dev/loop{0..3}
然后(如果这个大文件是电影)你可以将其所有权交给普通用户(chown itsme / dev / mapper / joined),然后他/她可以通过以下方式播放:mplayer / dev / mapper / joined < / p>
这些之后的清理(以root身份):
dmsetup remove joined; losetup -d /dev/loop[0123]
答案 4 :(得分:0)
不,没有这样的工具或系统调用。
您可以调查每个进程是否可以直接写入最终文件。假设进程1写入字节0-X,进程2写入X-2X等等。
答案 5 :(得分:0)
一种可能的替代方法是将所有临时文件捕获到命名管道中,然后使用该命名管道作为单输入程序的输入。只要你的单输入程序只是按顺序读取输入而不寻找。