Разрешение потоков из Python после вызова кода блокировки ввода-вывода в расширении Python, созданном с помощью SWIG
-
22-09-2019 - |
Вопрос
Я написал расширение Python, обертывающее существующую библиотеку C++. жить555 (точнее, оболочка клиентского интерфейса RTSP) в SWIG.Расширение работает, когда оно работает в одном потоке, но как только я вызываю функцию цикла событий библиотеки, интерпретатор Python никогда не возвращает управление.Итак, если я создаю запланированную задачу, используя threading.Timer
непосредственно перед вызовом цикла событий эта задача никогда не выполняется после запуска цикла событий.Чтобы исправить эту проблему, я добавил Py_BEGIN_ALLOW_THREADS
и Py_END_ALLOW_THREADS
макросы вручную в автоматически создаваемом файле-оболочке cxx SWIG вокруг каждого doEventLoop()
вызов функции.Но сейчас я хочу сделать то же самое (т.разрешить потоки), когда SWIG сам генерирует код и не изменять какой-либо код вручную.Кто-нибудь делал что-то подобное в SWIG?
P.S.- Я бы также рассмотрел возможность перехода на любую другую структуру (например, SIP), чтобы это заработало.Я предпочел SWIG любой другой технологии, потому что написать интерфейс SWIG было действительно очень легко, и мне просто нужно было включить существующие файлы заголовков.
Решение
SWIG предлагает множество способов, которые помогут это сделать.Если для ваших нужд достаточно грубого решения, я раньше делал что-то вроде этого в своем файле .swig:
%exception {
Py_BEGIN_ALLOW_THREADS
$action
Py_END_ALLOW_THREADS
}
Здесь (ab) используется возможность SWIG для украшения вызовов функций C некоторой логикой обработки ошибок, чтобы украсить эти вызовы разблокировкой/блокировкой GIL.Видеть Обработка исключений с помощью %Exception в документации SWIG для получения подробной информации о том, что здесь происходит.