1

I've run into an issue using PerlMagick under a restricted user account where this error occurs:

libgomp: Thread creation failed: Resource temporarily unavailable

I discovered that this can be fixed using either the general environmental variable setting export OMP_NUM_THREADS=1 or the ImageMagick specific one export MAGICK_THREAD_LIMIT=1. However, I'd like to integrate the correction into Perl itself, either by passing a configuration directly to PerlMagick (that seems like the "correct" fix) or by setting the environmental variable in the script.

I tried setting $ENV{'OMP_NUM_THREADS'} which did not solve the issue, even though setting that variable before running the script does work. Likewise, trying to run the export command from within the script had no effect.

Is there a better way to correct this?

Timothy R. Butler
  • 1,097
  • 7
  • 20
  • *"even though setting that variable before running the script does work"* It might be that the variable is checked by a shared library that is loaded by PerlMagick in a use statement in the beginning of your program. Then it will be too late to set the variable after the use statement has been executed – Håkon Hægland Jun 02 '23 at 07:45

2 Answers2

2

It sounds like your environment variable needs to be defined before PerlMagick is loaded. If this is true, there are two ways to do this inside Perl.

You can set the environment variable in a BEGIN block before loading PerlMagick:

BEGIN { $ENV{MAGICK_THREAD_LIMIT} = 1 }
use Image::Magick;

The BEGIN block forces the assignment to occur as soon as it is compiled, and therefore before the use. If you do this, do not put a colon after the BEGIN. If you do, it is still valid Perl, but now it is simply a labelled block, which is executed at run time.

Or, you can set the environment variable at run time before loading PerlMagick also at run time:

$ENV{MAGICK_THREAD_LIMIT} = 1;
require Image::Magick;

The require loads the module at run time rather than compile time, and therefore after the assignment gets executed. But it does not import any symbols into your name space. This is probably not a problem in your case, since Image::Magick has an O-O interface.

If you simply do

$ENV{MAGICK_THREAD_LIMIT} = 1;
use Image::Magick;

The use occurs at compile time, and therefore before the assignment statement is executed, even though the use appears after the assignment in the script.

user20284150
  • 242
  • 3
1

I would set it in my login script, e.g. ~/.bash_profile, or in the system-wide login script for all users, e.g. /etc/profile:

export MAGICK_THREAD_LIMIT=1

Another option might be to edit the system-wide ImageMagick resources.xml. You can find this using:

magick identify -list configure | grep -i xml

and it will be in the same directory as policy.xml.

Extra ideas here and here.


The hardest option would be to rebuild ImageMagick from source. In that case, you'd need:

./configure --disable-openmp ...
make -j
sudo make install
sudo ldconfig
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432