Why is Image.write() blocking all threads?

Magick++ is an object-oriented C++ interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick++.
Post Reply
josh3736
Posts: 8
Joined: 2013-07-12T12:42:16-07:00
Authentication code: 6789

Why is Image.write() blocking all threads?

Post by josh3736 »

I'm trying to perform ImageMagick operations on a thread pool (using libuv).

Each worker thread creates its own Magick::Image instance, does some stuff (different image data and options for every request), and eventually calls Image.write(<freshly allocated Magick::Blob>).

I've noticed that every thread does all its work up to the point where write() is called, and then blocks. It looks like each thread's call to write() does not begin to execute until after the last thread's write() returns, and my CPU usage never crosses 12% (8 core machine).

Why is this happening?
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Why is Image.write() blocking all threads?

Post by magick »

Most coders are multi-threaded, a few are not because ImageMagick depends on a delegate library that is not threaded. An example is JPEG. The JPEG library is not threaded so we can only write one JPEG image at a time. The other single threaded image formats are JPEG-2000 and TIFF. Are you writing an image in one of these formats? If not, let us know which format you're writing and we will investigate further.
josh3736
Posts: 8
Joined: 2013-07-12T12:42:16-07:00
Authentication code: 6789

Re: Why is Image.write() blocking all threads?

Post by josh3736 »

Thanks for the reply. I'm taking in BMP images and trying to output PNG.
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: Why is Image.write() blocking all threads?

Post by dlemstra »

The png coder uses 'SETJMP_IS_THREAD_SAFE' to determine if it needs a lock. What is your operating system?
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
josh3736
Posts: 8
Joined: 2013-07-12T12:42:16-07:00
Authentication code: 6789

Re: Why is Image.write() blocking all threads?

Post by josh3736 »

Windows 8.1
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: Why is Image.write() blocking all threads?

Post by glennrp »

dlemstra wrote:The png coder uses 'SETJMP_IS_THREAD_SAFE' to determine if it needs a lock. What is your operating system?
Years ago allegations were made to the PNG developers that some operating systems have a setjmp() that is not thread safe. But we've never been told
which setjmp() implementations are thread-safe and which are not, so since then all have been treated as unsafe. The intent was to add
#defines at line 625 in coders/png.c to set SETJMP_IS_THREAD_SAFE for platforms known to be safe.
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: Why is Image.write() blocking all threads?

Post by glennrp »

josh3736 wrote:Windows 8.1
Do you know if your libpng uses setjmp()? Libpng does by default, but it can be defined out when you
configure libpng, and we should add a test for PNG_SETJMP_SUPPORTED in coders/png.c
to avoid the blockage.
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: Why is Image.write() blocking all threads?

Post by dlemstra »

The Windows distribution of ImageMagick currently uses 1.6.10 and PNG_SETJMP_SUPPORTED is defined. I will have to check if setjmp is thread safe under Windows and define IMPNG_SETJMP_IS_THREAD_SAFE if it is.

Edit: It is safe under Windows and the define has been added.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
Post Reply