Как избежать проблем с жизненным циклом pybind11 - PullRequest
0 голосов
/ 01 ноября 2019

Я пишу запросы ReST API в Python. Эти запросы вызываются и доставляются в C ++ (Qt) с использованием pybind11. Желаемая функциональность работает должным образом, но я получаю следующее предупреждение при многократном выполнении сценария:

context.c:55: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time

Мне удалось сузить источник предупреждения до импорта python requestsпакет, который вызывается из моего скрипта.

Вот минимальный пример того, как выглядит выполнение скрипта из C ++:

// member of MyWidget
void callMyPythonScript()
{
    py::scoped_interpreter guard{};
    py::module sys = py::module::import("sys");
    auto locals = py::dict("my_scripts"_a="/path/to/my/python-scripts");
    py::exec(R"(
        import sys
        sys.path.insert(0, '{my_scripts}'.format(**locals()))
    )", py::globals(), locals);

    py::module my_script = py::module::import("my_script");
}

Содержимое my_script.py - это одна строка:

import requests

callMyPythonScript подключен к нажатию кнопки на стороне C ++ с использованием архитектуры слотов сигналов Qt:

connect(button_, &QPushButton::clicked,
        this, &MyWidget::callPythonCode);

Я не получил предупреждение ни с какими другими пакетамичем requests.

По документам pybind11 Возможно, у меня уже есть ответ на все это:

Модули, созданные с помощью pybind11, можно безопасно перезапустить. инициализируется после перезапуска интерпретатора. Однако это может не относиться к сторонним модулям расширения. Проблема в том, что сам Python не может полностью выгрузить модули расширения, и есть несколько предостережений относительно перезапуска интерпретатора. Короче говоря, не вся память может быть освобождена либо из-за циклов ссылок Python, либо из-за созданных пользователем глобальных данных.

Тем не менее, создание вышеупомянутой архитектуры без проблем с памятью было бы тем, что я искал. Может кто-нибудь здесь предложить рабочий процесс, чтобы исправить это? Может быть, реализация интерпретатора на основе CPython?

РЕДАКТИРОВАТЬ: Вдобавок к комментарию @ jdehesa, я проверял C Api для Python. У меня вообще сложилось впечатление, что я смогу решить мою проблему с ним. Но, как уже утверждают многие другие ресурсы в сети, этот подход выглядит совсем другим зверем по сравнению с pybind11. Даже в документации по pybind11 говорится, что нужно соблюдать осторожность при смешивании функций C Api.

На данный момент я собираюсь полностью отказаться от Python для обработки запросов и перенесу соответствующие функции обратно в C ++.

Если кто-то захочет предложить поддержку, не стесняйтесь обратиться. Мне все еще интересно найти решение, и я поделюсь любыми результатами с сообществом в SO.

...