Python & C / C++ многопоточность: запуск нескольких потоков, выполняющих python в фоновом режиме C



У меня есть очень специфическая потребность :
Я хочу создать консоль python с виджетом Qt и иметь возможность иметь несколько независимых интерпретаторов.
Теперь позвольте мне попытаться объяснить, где мои проблемы и все попытки, которые я сделал, в порядке тех, которые я больше всего хотел бы сделать работающими с теми, которые я могу использовать по умолчанию





  • Первый момент заключается в том, что все функции в Python C API (PyRun[...], Пьеваль[...] ...) нужно, чтобы GIL был заблокирован, что запрещает любые параллельные интерпретации кода из C ( или я был бы очень рад, что ошибся !!! :D)



  • Поэтому я попробовал другой подход, чем "обычный способ": я сделал цикл в python, который вызывает read() в моем специальном файле и оценивает результат. Эта функция (реализованная в виде встроенного расширения) блокируется до тех пор, пока не появятся данные для чтения. (На самом деле, это в настоящее время некоторое время в C-коде, а не условие на основе pthread)
    Затем с помощью PyRun_simpleString () я запускаю свой цикл в другом потоке. Вот где проблема : моя функция чтения, в дополнение к заблокируйте текущий поток (это абсолютно нормально), он блокирует весь интерпретатор, и PyRun_simpleString () не возвращается...



  • Наконец, у меня есть последняя идея, которая рискует быть относительно медленной : иметь выделенный поток в C++, который запускает интерпретатор, и делать все в python для управления вводом/выводом. Это может быть цикл, который создает задания, когда есть консоль, нуждающаяся в выполнении команды. Кажется, это не очень трудно сделать, но я предпочитаю спросить вас : есть ли способ сделайте так, чтобы вышеперечисленные возможности работали, или есть другой способ, о котором я не думал, или моя последняя идея лучшая ?


622   2  

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

    Ничего не найдено.