[Python-ideas] adding an __exec__ method to context managers?

Ryan Freckleton ryan.freckleton at gmail.com
Tue Oct 13 17:27:04 CEST 2009


On Mon, Oct 12, 2009 at 7:46 PM, Sturla Molden <sturla at molden.no> wrote:
>
> I have been trying to implement an OpenMP-like threading API for Python. For
> those who don't know OpenMP, it is an alternative threading API for C, C++
> and Fortran, that unlike pthreads and Win32 threads has an intuitive syntax.
<snip>
>
> The virtue is that one can take sequential code, add in a few pragmas here
> and there, and end up having a multi-threaded program a human can
> understand. All the mess that makes multi-threaded programs error-prone and
> difficult to write is taken care of by the compiler.
>
> Ok, so what has this to do with Python?
>
> First Python already has the main machinery for OpenMP-like syntax using
> closures and decorators. For example, if we have a seqential function:
<snip>
> Now we could e.g. imagine using this syntax instead, using __exec__ to
> control execution in threads:
>
> def foobar():
>
>   with pymp.parallel_for( range(100) ) as mt:
>       for i in mt.iter:
>
>           dostuff1(i)
>
>           with mt.critical:
>               dostuff2(i)
>
>
> def foobar():
>       with pymp.parallel_sections as mt:
>           with mt.section:
>           task1()
>
>       with mt.section:
>           task2()
>
>       with mt.section:
>           task3()
>
>
<snip>

Have you looked at the API for python-safethread
[http://code.google.com/p/python-safethread/wiki/Branching]? I think
an API combining that and your semantics would be very cool.

If you use the same technique of passing functions into the context
manager, your examples become:

def foobar():
  with pymp.parallel_for(range(100)) as mt:
      for i in mt.iter:
          mt.add(lambda : dostuff1(i))
          mt.critical(lambda : dostuff2(i))

def foobar():
      with pymp.parallel_sections as mt:
          mt.section(task1)
          mt.section(task2)
          mt.section(task3)

Another option would be to execute the closure under the covers, e.g.

# The function dostuff_in_parallel is called when necessary by the pymp object.
@pymp.parallel_for(range(100))
def dostuff_in_parallel(mt):
    dostuff1(i)
    with mt.critical:
        dostuff2(i)

# The function sections is called when necessary by the pymp object,
e.g. by the parallel_sections decorator.
@pymp.parallel_sections
def sections(mt):
    mt.section(task1)
    mt.section(task2)
    mt.section(task3)

There are a couple PEPs about adding blocks to python that were
rejected in favor of the more constrained with statement, so you may
want to look at those as well.

Cheers,
=====
--Ryan E. Freckleton



More information about the Python-ideas mailing list