【问题标题】:How can I configure ImageMagick to not use any temporary files?如何将 ImageMagick 配置为不使用任何临时文件?
【发布时间】:2017-01-05 17:00:02
【问题描述】:

我试图在不接触文件系统的情况下运行 ImageMagick:图像数据从内存/网络中读取,并以 blob 的形式写回套接字。

但是,ImageMagick 不断尝试写入临时文件,这些临时文件要么由于测试中止/失败而填满我的测试系统,要么导致磁盘极慢的系统出现问题:这是一个奇怪的限制,但我的许多转换主机都是嵌入的- 类似具有块设备的系统,非常响应任何操作都很慢,即使是stat()s。

问题:

  1. 有没有办法将 ImageMagick 配置为在图像处理期间不接触磁盘?假设 ImageMagick 将使用的所有必需模块都已加载,并且没有一个 ImageMagick 功能将处理转移到子进程将使用与文件系统的对话。

  2. 这样做有什么副作用?我可以接受不适合内存失败的处理,而不是退回到磁盘。

我正在使用 C++ 或 Perl ImageMagick API 进行转换,而不是 convert 实用程序。不过,如果另一个绑定支持这一点,我可以切换平台。

我的尝试

  • 我已将MAGICK_TEMPORARY_PATH 设置为不同的位置,包括POSIX 上的/dev/null/dev/null 有时似乎可以工作,但我的目标系统不是 POSIX,所以我不确定我是否可以指望它。与其欺骗临时文件管理系统,我更喜欢我可以信任的东西来首先禁用对临时文件的需求。
  • 我使用了registry:temporary-path 选项,结果相似。
  • 将各种临时路径选项设置为不存在/不可用的位置(例如/dev/null 或不可写位置)通常会导致在启动我的程序的目录中创建临时文件。如果该目录是不可写的,我已经看到在系统/tmp 目录中创建了临时文件,即使代码被告知不要使用它。这些似乎发生在特殊情况下(例如 segfaulting/OOMing/kill -9'd 情况),所以我认为文件可能会在这些地方正常创建,但通常会被清理。

【问题讨论】:

  • 是否可以创建一个内存磁盘并将 /tmp 放在那里(在两次连续启动之间,您会破坏 ram-disk,重新创建/重新安装它)?如果做不到这一点,是否可以从应用程序终止后删除 /tmp 的脚本启动程序?
  • ramdisk 选项是可能的;使用和清除/dev/shm 或类似的也是如此。两者都需要代码来处理以前硬中止(崩溃、段错误等)运行留下的混乱,并且后续运行必须清理它,所以它并不理想。自动清理 /tmp 并没有太大的作用,因为文件系统访问仍然必须首先发生(并减慢一切)。
  • 查看environment variables 的完整列表。也许尝试将MAGICK_DISK_LIMIT 设置为零并增加MAGICK_MEMORY_LIMIT
  • 增加内存限制似乎有所帮助,但我有兴趣在所有情况下防止临时文件使用——即使需要更多内存,最好还是失败。

标签: c++ perl imagemagick temporary-files tmp


【解决方案1】:

诀窍是将MAGICK_DISK_LIMIT=0MAGICK_AREA_LIMIT/MAGICK_AREA_LIMIT 设置为大于程序所需的最大内存的值。

#!/usr/bin/perl
BEGIN {
    $ENV{'MAGICK_DISK_LIMIT'  }='0';
    $ENV{'MAGICK_AREA_LIMIT'  }='1Mb';
    $ENV{'MAGICK_MEMORY_LIMIT'}='1Mb';
}

use Image::Magick;    
my $img = Image::Magick->new();
my $err = $img->Read('in.png');
die $err if $err;

如果 ImageMagick 超过了这个内存限制,它会死掉并显示如下消息:

Exception 450: Memory allocation failed `in.png' @ error/png.c/MagickPNGErrorHandler/1645 at ./imagemem.pl line 11.

你可以通过运行identify -list resource查看ImageMagick的默认限制

【讨论】:

    【解决方案2】:

    在使用命令行工具时,我不得不增加配置文件中的内存:

    /etc/ImageMagick-6/policy.xml:

    <!-- DEFAULT: <policy domain="resource" name="memory" value="256MiB"/> -->
    <policy domain="resource" name="memory" value="1024MiB"/> 
    

    与版本存在差异:8:6.9.7.4+dfsg-16ubuntu6.9 (Ubuntu 18.04) 默认工作,不写入临时文件,使用 256MiB,但使用 8:6.9.10.23+dfsg-2.1ubuntu11.2 ( Ubuntu 20.04)我必须像上面那样增加内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多