Is it possible to issue a GIL in front of a C function that blocks and can call back in Python?

I wrap a C function that performs a select operation and then processes incoming messages. I understand that when a C function is about to block, the correct way to call it when resolving other threads is:

Py_BEGIN_ALLOW_THREADS                                                  
blocking_function();
Py_END_ALLOW_THREADS

However, it happens that this function takes a callback pointer as a parameter. This callback is called to handle an incoming message that is pre-processed by C. I successfully completed this callback in a function that calls PyEval_CallObject(), which allows me to pass it a Python callback.

Now, when I add thread support, I am wondering if this is possible at the same time:

  • Release the GIL before invoking this blocking operation.
  • This locking operation will safely call the python interpreter back.

Will this cause problems? If so, is there a way around it?

Thank.

+3
source share
2 answers

I used these API functions a few months ago, and my memory is a little vague, but I believe that this code will solve your problem. I assume version 2.x (3.x may be different):

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

/* Make your call to PyEval_CallObject() here (and any other PY API calls). */

PyGILState_Release(gstate);

(Above was taken from: Python C / API Docs )

This is basically the inverse of Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS macros. Inside them, you release the GIL, but as part of the PyGILState functions, you get the GIL.

+7
source

, PyEval_SaveThread PyEval_RestoreThread. , .

+1

Source: https://habr.com/ru/post/1795572/


All Articles