Executing previous stack frame

Discussion in 'Python' started by sturlamolden, Jan 22, 2009.

  1. sturlamolden

    sturlamolden Guest

    frame = sys._getframe().f_back is the previous stack frame. Is there
    any way to execute (with exec or eval) frame.f_code beginning from
    frame.f_lasti or frame.f_lineno?

    I am trying to spawn a thread that is initialized with the code and
    state of the previous stack frame.


    S.M.
     
    sturlamolden, Jan 22, 2009
    #1
    1. Advertising

  2. sturlamolden

    Jeff McNeil Guest

    On Jan 22, 9:49 am, sturlamolden <> wrote:
    > frame = sys._getframe().f_back is the previous stack frame. Is there
    > any way to execute (with exec or eval) frame.f_code beginning from
    > frame.f_lasti or frame.f_lineno?
    >
    > I am trying to spawn a thread that is initialized with the code and
    > state of the previous stack frame.
    >
    > S.M.


    What are you trying to accomplish? While it's possible to do, I can't
    believe it's going to be very safe. Note that I'd never even consider
    doing anything like this for anything of real consequence. That said,
    it was kind of fun to figure out just for academic purposes...

    import sys
    import types
    import threading

    def do_something_we_should_not_do():
    back = sys._getframe().f_back
    code_object = back.f_code

    # Skip CALL_FUNCTION & POP_TOP, otherwise we create
    # a loop.
    code = code_object.co_code[back.f_lasti+4:]

    def tmain():
    c = types.CodeType(code_object.co_argcount,
    code_object.co_nlocals,
    code_object.co_stacksize, code_object.co_flags, code,
    code_object.co_consts, code_object.co_names,
    code_object.co_varnames,
    code_object.co_filename, code_object.co_name,
    code_object.co_firstlineno,
    code_object.co_lnotab)
    exec c in globals()

    threading.Thread(target=tmain).start()

    do_something_we_should_not_do()

    # Anything below here will run in both threads.
    print threading.current_thread()

    Thanks,

    Jeff
    mcjeff.blogspot.com
     
    Jeff McNeil, Jan 22, 2009
    #2
    1. Advertising

  3. sturlamolden

    sturlamolden Guest

    On Jan 22, 8:47 pm, Jeff McNeil <> wrote:

    > What are you trying to accomplish?



    On Jan 22, 8:47 pm, Jeff McNeil <> wrote:

    > What are you trying to accomplish? While it's possible to do, I can't
    > believe it's going to be very safe.


    I am trying to implement a completely new concurrency abstraction for
    Python. It is modeled on OpenMP instead of Java threads (cf. threading
    and multiprocessing). I am planning to use thread and multiprocessing
    (or os.fork) as backends. Doing this with os.fork is child's play, but
    it would not work on Windows.

    I believe Python context managers are excellent for this purpose. I
    believe the OpenMP way of doing concurrency fits better with the mind
    than Java threading, and thus are more pythonic. Algorithms can be
    written as sequential, and transformed to parallel code with the
    simple insertion of a few directives. It makes debugging easier,
    because one can debug the sequential code, and it makes it easier to
    avoid the problems with deadlocks, race conditions, livelocks, etc.
    Just ask any C or Fortran programmer how much easier it is to use
    OpenMP instead of Win32 or Posix threads.

    What I have in mind is an API that would look approximately like this
    (OpenMP pragmas for C on top, proposed Python equivalent below):


    #pragma omp parallel
    with Pool() as pool:

    #pragma omp for
    for item in pool.parallel(<iterable>):

    #pragma omp for shedule(guided)
    for item in pool.parallel(<iterable>, shed='guided'):

    #pragma omp parallel for
    with Pool() as pool:
    for item in pool.parallel(<iterable>):

    #pragma omp barrier
    pool.barrier()

    #pragma omp section
    with pool.section():

    #pragma omp parallel sections
    with Pool() as pool:
    with pool.section():
    fun1(*args, **kwargs)
    with pool.section():
    fun2(*args, **kwargs)

    #pragma omp master
    if pool.master:

    #pragma omp critical
    #pragma omp atomic
    with pool.lock:

    #pragma omp single
    with pool.single():

    #pragma omp ordered
    with ordered(k):


    Here is a toy example of what I have in mind. Say you would want to
    compute the DFT of some signal (real apps would use an FFT in C for
    this, but never mind that). In Python using an O(n**2) algorithm, this
    would look like something like this:


    def real_dft(x):
    ''' DFT for a real valued sequence x '''
    r = []
    N = len(x)
    M = N//2 + 1 if N%2 else N//2
    for n in range(M):
    s = 0j
    for k in range(N):
    tmp = 2*pi*k*n/N
    s += x[k] * (cos(tmp) - 1j*sin(tmp))
    r.append(s)
    return r


    Then, one could 'magically' transform this algorithm into to a
    parallel one simply by inserting directives from the 'OpenMP' module:


    def real_dft(x):
    ''' DFT for a real valued sequence x '''
    ''' parallelized '''
    r = []
    N = len(x)
    M = N//2 + 1 if N%2 else N//2
    with Pool() as pool:
    parallel_iter = pool.parallel(range(M)):
    for n in parallel_iter:
    s = 0j
    for k in range(N):
    tmp = 2*pi*k*n/N
    s += x[k] * (cos(tmp) - 1j*sin(tmp))
    with parallel_iter.ordered(n):
    r.append(s)
    return r


    The idea is that 'parallelizing' a sequential algorithm like this is
    much easier than writing a parallel one from scratch using the
    abstractions in threading or multiprocessing.

    The problem is that the __enter__ method of the Pool object (the
    context manager) must spawn multiple threads, each executing
    sys._getframe().f_back, because the 'with Pool() as pool:' should be
    executed by multiple threads in parallel. These slave threads will be
    killed when they enter the __exit__ method of its context manager.

    Most of this OpenMP API has already been implemented. I just need the
    machinery to make the slave threads come alive :)

    I'll take a look at your code now :)



    Regards,
    Sturla Molden
     
    sturlamolden, Jan 22, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sven
    Replies:
    2
    Views:
    5,106
    tragomaskhalos
    Nov 30, 2007
  2. Surinder Singh
    Replies:
    1
    Views:
    1,206
    Richard Bos
    Dec 20, 2007
  3. Mahesh
    Replies:
    31
    Views:
    1,619
    Richard Bos
    Mar 3, 2008
  4. Dai Ba Wong
    Replies:
    3
    Views:
    160
    kaeli
    Jul 6, 2004
  5. Mark Wood-Patrick
    Replies:
    0
    Views:
    99
    Mark Wood-Patrick
    Jul 30, 2003
Loading...

Share This Page