[SciPy-user] Multithreading cookbook entry

Anne Archibald peridot.faceted@gmail....
Thu Feb 21 13:00:56 CST 2008

On 21/02/2008, Lou Pecora <lou_boog2000@yahoo.com> wrote:
>  (1) In your code if return_ = True I get a return
>  value from the foreach function only when nthreads>1,
>  but not when nthreads=1.  Looking at the code the
>  nthreads=1 ends up in the else: at the bottom which
>  looks like:
>         else:
>                 if return_:
>                         for v in l:
>                                 f(v)
>                 else:
>                         return
>  and is puzzling.  Nothing is returned in the if part
>  and f is not even called in the else part.  Is this a
>  bug?

Yep. Oops. Fixed in the v2 versions of the files. The wiki doesn't
make a very good version control system. Is it worth incorporating
those files into scipy?

>  (2) If I replace the sleep(0.5) call in your f
>  function with a loop that just does a simple
>  calculation to eat up time, then in the call to
>  foreach when nthreads=2 the time to run the code goes
>  up by factors of ~100 or so.  I'm guessing here that
>  it's because the GIL is not release for my version,
>  but is release in the sleep(0.5) function in your
>  version.  Is that right?

Depends what your function does, really. If your function takes half a
second but never releases the GIL, it should take twice as long. If
your function releases the GIL, then it should take about the same
time. But it's quite tricky to write a function that works hard and
releases the GIL. A good rule of thumb is to count the lines of python
that are getting executed. If there are only a few - say you're doing
sum(log(exp(arange(1000000)))) - there's a good chance the GIL will be
released. If you're running millions of python instructions, the GIL
is held all that time, and you won't get a speedup.

>  (3) You mention that ctypes probably doesn't release
>  the GIL. I would guess that too, since it would be
>  dangerous as I (vaguely) understand the GIL.  But does
>  the GIL have to be released in the Cextension or can
>  it be release in the step just before I call the C
>  extension from Python? I.e. is release on the Python
>  side possible?  If not, I guess I will have to look
>  over the numpy code as you suggest.  If possible, I
>  suppose the GIL must be enabled immediately on return
>  from the C extension.

You can't execute any python bytecodes without holding the GIL, so
it's impossible for python code to release the GIL. But it would be
perfectly possible, in principle, for SWIG, F2PY, or ctypes to put a
"release the GIL" in their wrappers. This will be a problem for some
functions - either ones that aren't reentrant, or ones that call back
to python (though in principle it might be possible to reacquire the
GIL for the duration of a callback). But for a typical C function that
acts only on data you give it and that doesn't know anything about
python, it should be safe to run it without the GIL engaged. It seems
like f2py can actually do this for functions marked as threadsafe; I
don't know about ctypes or SWIG.


More information about the SciPy-user mailing list