PIL的resize()函数是否持有GIL锁?

4

例子:

image = Image.open('foo.png')
# releases the GIL?
resized = image.resize((800, 600), Image.ANTIALIAS)
# reacquires the GIL?

很显然,变量赋值需要持有GIL,但将其拆分为两行比较困难。 :)

如果有两个线程在进行图像调整大小,这些调整大小能够在两个不同的核心上运行吗?

2个回答

3

看源码1.1.7,似乎没有在_resize中释放GIL。

释放GIL的函数似乎是:

PyImaging_CreateWindowWin32 (createwindow on Win32)
PyImaging_EventLoopWin32 (eventloop on Win32)
pyCMSdoTransform (apply)
_buildTransform (buildTransform)
_buildProofTransform (buildProofTransform)
_encode_to_file (encode_to_file)

GIL也可以通过PyEval_SaveThread()调用来释放,该调用由ImagingSectionEnter()调用,在数十个地方调用。因此,GIL似乎被相当积极地释放。(尽管在图像加载期间显然不是这样。) - Lawrence Kesteloot

1

来自Python GIL wiki

请注意,潜在的阻塞或长时间运行的操作,例如I/O、图像处理和NumPy数值计算,发生在GIL之外。因此,只有在多线程程序中,花费大量时间在GIL内部解释CPython字节码时,GIL才会成为瓶颈。

PIL使用C扩展来完成大部分重活。因此,如果适用,实际的图像调整应该利用多线程。

如果您想同时调整多个图像,请考虑使用Python本地的multiprocessing库。这应该可以实现使用多个核心的期望效果。


gevent 不允许您使用多个核心。 - r3m0t
11
虽然允许C扩展程序释放GIL,但这并不意味着它们总是这样做。扩展程序开发人员必须显式调用Py_BEGIN_ALLOW_THREADS。http://docs.python.org/2/c-api/init.html#releasing-the-gil-from-extension-code - bobpoekert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接