Impasse quando o QThread tenta adquirir o Python GIL via PyGILState_Ensure ()

Eu tenho um aplicativo C ++ / Qt no qual desejo incorporar o interpretador Python. Quero chamar Python a partir de um QThread, mas estou obtendo um impasse na linha em que chamo PyGILState_Ensure () para tentar adquirir o bloqueio global de intérpretes (GIL).

Vou fornecer um exemplo mínimo e direto abaixo, que segue as recomendações fornecidasaqui:

//main.cpp:
#include <QCoreApplication>
#include <QThread>
#include "Worker.h"

void startThread()
{
    QThread* thread = new QThread;
    Worker* worker = new Worker();
    worker->moveToThread(thread);
    QObject::connect(thread, SIGNAL(started()), worker, SLOT(process()));
    QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
    QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Py_Initialize();
    startThread();
    Py_FinalizeEx();
    return a.exec();
}


//Worker.h:
#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include "Python.h"

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr) : QObject(parent) {}

Q_SIGNALS:
    void finished();

public Q_SLOTS:
    void process()
    {
        qDebug("Calling Python");
        PyGILState_STATE gstate = PyGILState_Ensure();
        PyRun_SimpleString("print(\"hello\")");
        PyGILState_Release(gstate);
        qDebug("Done calling Python");
        Q_EMIT finished();
    }
};

#endif // WORKER_H

Alguns comentários adicionais:

Nota: O arquivo .pro contém a linhaCONFIG += no_keywords, para evitar conflitos de nome com o cabeçalho Python.Deve-se notar que, enquanto o encadeamento interrompe a execução na chamada para PyGILState_Ensure (), o encadeamento principal continua desinibido. Se eu mudarreturn a.exec(); parareturn 0;, o programa será encerrado. (Portanto, talvez deadlock seja o termo errado a ser usado.)Observe que não estou interessado em criar threads no Python. Eu só quero chamar diretamente um determinado script Python de um QThread.Eu li outrosemelhante questões, mas consideramos que os casos considerados são sutilmente diferentes e não consegui resolver meu problema com as respostas dadas lá. Além disso, estou confuso com as recomendações para ligarPyEval_InitThreads(), que se eu entender oDocumentação da API Python / C corretamente, não deve ser necessário.

questionAnswers(1)

yourAnswerToTheQuestion