Разрешение потоков из Python после вызова блокирующего кода ввода / вывода в расширении Python, созданном с использованием SWIG - PullRequest
1 голос
/ 24 марта 2010

Я написал расширение Python, упаковывающее существующую библиотеку C ++ live555 (конкретизирующее интерфейс клиента RTSP) в SWIG. Расширение работает, когда оно работает в одном потоке, но как только я вызываю функцию цикла событий библиотеки, интерпретатор python никогда не возвращает управление обратно. Поэтому, если я создаю запланированную задачу, используя threading.Timer непосредственно перед вызовом цикла событий, эта задача никогда не будет выполнена после запуска цикла событий. Чтобы устранить эту проблему, я добавлял макросы Py_BEGIN_ALLOW_THREADS и Py_END_ALLOW_THREADS вручную в SWX-файл автоматически генерируемой оболочки SWIG вокруг каждого вызова функции doEventLoop(). Но теперь я хочу сделать то же самое (т.е. разрешить потоки), когда SWIG генерирует сам код, а не изменять какой-либо код вручную. Кто-нибудь делал что-то подобное в SWIG?

P.S. - Я бы также рассмотрел возможность перехода на любую другую среду (например, SIP), чтобы это работало. Я выбрал SWIG вместо любой другой технологии, потому что написание интерфейса SWIG было действительно очень простым, и мне просто нужно было включить существующие заголовочные файлы.

1 Ответ

3 голосов
/ 25 марта 2010

SWIG дает вам множество хуков, чтобы помочь этому случиться. Если для ваших нужд достаточно грубого решения, то одна вещь, которую я делал в прошлом, помещает что-то вроде этого в мой файл .swig:

%exception {
    Py_BEGIN_ALLOW_THREADS
    $action
    Py_END_ALLOW_THREADS
}

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

...