Saltar al contenido

Usar QThread y moveToThread correctamente con QTimer y QTcpSocket

Solución:

Las instancias de clase se crean en el hilo de llamada.
QTimer hereda QObject. Cada hilo en Qt puede tener un bucle de eventos si llama exec(). entonces quieres moverte QTimer a un bucle de eventos en otro hilo. por lo que debe moverlo manualmente.

Por lo tanto, retrase su creación hasta después de mover el objeto: –

class CommsHandlerIP : public QObject
{
    Q_OBJECT

    public slots:
       void Initialise();

    private: 
       void Run();

       // c++ 11, initialising in headers...
       QTimer* m_pTimer = NULL;
       QTcpSocket* m_pSocket = NULL;   
};

void CommsHandlerIP::Initialise()
{
     m_pTimer = new QTimer(this);
     m_pSocket = new QTcpSocket(this);

     Run();
}

QThread m_commsThread;
m_pICommsHandler = new CommsHandlerIP();

// Note Qt 5 connect style
connect(&m_commsThread, &QThread::started, m_pICommsHandler, &CommsHandlerIP::Initialise);
m_pICommsHandler->moveToThread(&m_commsThread);
m_commsThread.start();

Cuando se inicia el hilo, el CommsHanderIP Inicializar se llama a la función; aquí es donde debe crear y configurar el QTcpSocket y QTimer objetos antes de llamar Run(). Como el CommsHandlerIP se está ejecutando en el nuevo hilo antes de crear esos objetos, también compartirán la misma afinidad de hilo.

Existe un método mucho más simple para lograr todo esto que sigue el mismo algoritmo pero no involucra todo el repetitivo necesario para crear hilos y cambiar afinidades de hilo, usando QRunnable y QThreadPool

Si convierto el ejemplo de Merlin069, verás cómo simplifica un poco el código:

class CommsHandlerIP : public QObject, public QRunnable
{
    Q_OBJECT
    public:
       void run();

    public slots:
        //... any slots

    signals:
        //... any signals

    private:
       // c++ 11, initialising in headers...
       QTimer* m_pTimer = NULL;
       QTcpSocket* m_pSocket = NULL;   
};

void CommsHandlerIP::run()
{
     m_pTimer = new QTimer();
     m_pSocket = new QTcpSocket();

     //...

     delete m_pTimer;
     delete m_pSocket;
}

QThreadPool::globalInstance()->start(new CommsHandlerIP);

Me encontré con esto al buscar el comportamiento del temporizador y moverme a Thread. La respuesta aceptada es una buena solución, pero no es realmente la causa raíz del problema. Existe una regla general de que cuando mueva un objeto, todos los objetos secundarios también se moverán. Por lo tanto, solo debe asegurarse de que QTimer se convierta en un niño, así que pase el puntero this en su constructor.

CommsHandlerIPL::CommsHandlerIP()
: QObject(), m_pTimer(new QTimer(this))        // <=== crucial to make it a "child" object 
{
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *