Можно ли выпустить GIL перед функцией C, которая блокирует и может вызывать обратно в Python? - PullRequest
4 голосов
/ 01 марта 2011

Я обертываю функцию C, которая выполняет операцию блокировки (выбор), а затем обрабатывает входящие сообщения.Насколько я понимаю, когда функция C собирается блокировать, правильный способ ее вызова при одновременном запуске других потоков:

Py_BEGIN_ALLOW_THREADS                                                  
blocking_function();
Py_END_ALLOW_THREADS

Однако бывает, что эта функция принимает в качестве параметра указатель обратного вызова,Этот обратный вызов вызывается при обработке входящего сообщения, которое предварительно обрабатывается функцией C.Я успешно завернул этот обратный вызов в функцию, которая вызывает PyEval_CallObject(), что позволяет мне передать ему обратный вызов Python.

Теперь, когда я добавляю поддержку потоков, мне интересно, возможно ли это одновременно:

  • Перед вызовом этой операции блокировки отпустите GIL.
  • Пусть эта операция блокировки безопасно перезвонит в интерпретатор python.

Будет ли это вызывать проблемы?Если так, есть ли способ обойти это?

Спасибо.

Ответы [ 2 ]

7 голосов
/ 01 марта 2011

Я использовал эти функции API несколько месяцев назад, и мои воспоминания немного туманные, но я верю, что этот код решит вашу проблему. Я предполагаю, что версия 2.x (3.x может отличаться):

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

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

PyGILState_Release(gstate);

(Выше взято из: Документы Python C / API )

Это в основном обратное Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS макросы. Внутри них вы освобождаете GIL, но в функциях PyGILState вы получаете GIL.

1 голос
/ 01 марта 2011

Работает, если я использую глобальный для хранения результата PyEval_SaveThread, и использую это в обратном вызове для вызова PyEval_RestoreThread.Мне просто нужно выяснить, как более четко передать это обратному вызову в моем коде через указатель контекста обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...