Punto muerto cuando QThread intenta adquirir Python GIL a través de PyGILState_Ensure ()

Tengo una aplicación C ++ / Qt en la que quiero incrustar el intérprete de Python. Quiero llamar a Python desde un QThread, pero obtengo un punto muerto en la línea donde llamo PyGILState_Ensure () para intentar adquirir el bloqueo global del intérprete (GIL).

Proporcionaré un ejemplo mínimo y directo a continuación, que sigue las recomendaciones dadasaquí:

//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

Algunos comentarios adicionales:

Nota: el archivo .pro contiene la líneaCONFIG += no_keywords, para evitar conflictos de nombres con el encabezado de Python.Cabe señalar que mientras el hilo detiene la ejecución en la llamada a PyGILState_Ensure (), el hilo principal continúa sin inhibiciones. Si cambioreturn a.exec(); areturn 0;, el programa saldrá. (Entonces quizás el punto muerto sea el término incorrecto para usar).Tenga en cuenta que no estoy interesado en crear hilos desde Python. Solo quiero llamar directamente a un script de Python dado desde un QThread.He leído otrosimilar preguntas, pero consideró que los casos considerados allí son sutilmente diferentes, y no he podido resolver mi problema con las respuestas dadas allí. Además, estoy confundido por las recomendaciones para llamarPyEval_InitThreads(), que si entiendo elDocumentación de API Python / C correctamente, no debería ser necesario.

Respuestas a la pregunta(1)

Su respuesta a la pregunta