Using Py_AddPendingCall

Discussion in 'Python' started by css322, Sep 16, 2012.

  1. css322

    css322 Guest

    I have an embedded Python program which runs in a thread in C.

    When the Python interpreter switches thread context (yielding control to another thread), I'd like to be notified so I can perform certain necessary operations.

    It seems that Py_AddPendingCall is exactly what I'm looking for. However, the API docs are pretty brief on this function, and I'm confused as to how Py_AddPendingCall is supposed to be used. From reading the docs, my understanding is that:

    (1) A worker thread calls Py_AddPendingCall and assigns a handler function.
    (2) When the Python interpreter runs, it calls the handler function whenever it yields control to another thread
    (3) The handler itself is executed in the main interpreter thread, with the GIL acquired

    I've googled around for example code showing how to use Py_AddPendingCall, but I can't find anything. My own attempt to use it simply doesn't work. The handler is just never called.

    My worker thread code:

    const char* PYTHON_CODE =
    "while True:\n"
    " for i in range(0,10): print(i)\n"
    "\n";

    int handler(void* arg)
    {
    printf("Pending Call invoked!\n");
    abort();
    }

    void worker_thread()
    {
    PyGILState_STATE state = PyGILState_Ensure();
    Py_AddPendingCall(&handler, NULL);
    PyRun_SimpleString(PYTHON_CODE);
    PyGILState_Release(state);
    }

    In this example, worker_thread is invoked in C as a pthread worker thread. This loops infinitely, but the pending call handler is never invoked.

    So,obviously I'm not understanding the docs correctly. How is Py_AddPendingCall is supposed to be used?
    css322, Sep 16, 2012
    #1
    1. Advertising

  2. css322 <charles.salvia316 <at> gmail.com> writes:
    >
    > (1) A worker thread calls Py_AddPendingCall and assigns a handler function.
    > (2) When the Python interpreter runs, it calls the handler function whenever

    it yields control to another thread

    Not exactly. As the documentation says: "If successful, func will be called
    with the argument arg *at the earliest convenience*."
    This is a deliberately vague wording to stress that the function will not be
    called as early as you think. It *should* be called in a timely manner, but not
    necessarily as soon as the thread switch happens.

    Which begs the question:

    > In this example, worker_thread is invoked in C as a pthread worker thread. This
    > loops infinitely, but the pending call handler is never invoked.


    What is your main Python thread doing? Is it running Python code (*)? Or do you
    have a main Python thread at all? The "main Python thread" is the one from which
    Py_Initialize() was called.

    (*) for example, running one of the following functions:
    http://docs.python.org/dev/c-api/veryhigh.html

    Regards

    Antoine.
    Antoine Pitrou, Sep 17, 2012
    #2
    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. William F. Robertson, Jr.
    Replies:
    1
    Views:
    958
    Kathy Burke
    Jun 25, 2003
  2. pete
    Replies:
    1
    Views:
    2,919
    Jon Yates
    Aug 29, 2003
  3. timmso
    Replies:
    1
    Views:
    465
    Alex Papadimoulis
    Dec 12, 2003
  4. Replies:
    2
    Views:
    531
  5. =?Utf-8?B?R1REcml2ZXI=?=
    Replies:
    1
    Views:
    3,806
    Karl Seguin
    Feb 16, 2005
Loading...

Share This Page