Python & C / C++ многопоточность: запуск нескольких потоков, выполняющих python в фоновом режиме C
У меня есть очень специфическая потребность :
Я хочу создать консоль python с виджетом Qt и иметь возможность иметь несколько независимых интерпретаторов.
Теперь позвольте мне попытаться объяснить, где мои проблемы и все попытки, которые я сделал, в порядке тех, которые я больше всего хотел бы сделать работающими с теми, которые я могу использовать по умолчанию
Первый момент заключается в том, что все функции в Python C API (PyRun[...], Пьеваль[...] ...) нужно, чтобы GIL был заблокирован, что запрещает любые параллельные интерпретации кода из C ( или я был бы очень рад, что ошибся !!! :D)
Поэтому я попробовал другой подход, чем "обычный способ": я сделал цикл в python, который вызывает read() в моем специальном файле и оценивает результат. Эта функция (реализованная в виде встроенного расширения) блокируется до тех пор, пока не появятся данные для чтения. (На самом деле, это в настоящее время некоторое время в C-коде, а не условие на основе pthread)
Затем с помощью PyRun_simpleString () я запускаю свой цикл в другом потоке. Вот где проблема : моя функция чтения, в дополнение к заблокируйте текущий поток (это абсолютно нормально), он блокирует весь интерпретатор, и PyRun_simpleString () не возвращается...
Наконец, у меня есть последняя идея, которая рискует быть относительно медленной : иметь выделенный поток в C++, который запускает интерпретатор, и делать все в python для управления вводом/выводом. Это может быть цикл, который создает задания, когда есть консоль, нуждающаяся в выполнении команды. Кажется, это не очень трудно сделать, но я предпочитаю спросить вас : есть ли способ сделайте так, чтобы вышеперечисленные возможности работали, или есть другой способ, о котором я не думал, или моя последняя идея лучшая ?
2 ответов:
Одна из альтернатив - просто повторно использовать код из IPython и егоQt Console . Это предполагает, что независимые интерпретаторы подразумевают, что они не будут делиться памятью. IPythons запускает интерпретатор Python в нескольких процессах и взаимодействует с ними через TCP или Unix доменные сокеты с помощью ZeroMQ.
Кроме того, из вашего вопроса я не уверен, знаете ли вы о распространенной блокировочной идиоме ввода-вывода в расширениях Python C:
Py_BEGIN_ALLOW_THREADS ... Do some blocking I/O operation ... Py_END_ALLOW_THREADSЭто освобождает GIL так, что другие потоки могут выполнять код Python, пока ваша функция блокируется. Смотритесправочное руководство по API Python/C: Состояние потока и глобальная блокировка интерпретатора .
Если ваше основное требование состоит в том, чтобы иметь несколько интерпретаторов независимых друг от друга, вам, вероятно, лучше подойдет выполнение fork() и exec (), чем многопоточность.
Таким образом, каждый из интерпретаторов будет жить в своем собственном адресном пространстве, не мешая другим.
Comments