Pregunta

Tengo un subproceso principal que invoca una función de subproceso secundario en diferentes momentos, pero no estoy seguro de si esa es la forma correcta de hacerlo en Qt.

Hay un subproceso principal que se ejecuta infinitamente cuando el subproceso principal se libera, el elemento secundario de bloqueo hace un trabajo.

#include <QtCore/QCoreApplication>
#include <QSemaphore>
#include <QThread> 
QSemaphore sem(0);
class Background : public QThread 
{
protected:
void run() 
{ 
for(;;)
{ 
   sem.acquire(1); 
   qDebug("Child function ran");
} 
} 
};

int main(int argc, char *argv[])  
{   
QCoreApplication a(argc, argv);   
Background child; 
child.start();
qDebug("Main running"); 
qDebug("release a lock");
sem.release(1);
qDebug("Do somework in main");   
//call child
sem.release(1);
sem.release(1);
return a.exec();  
}
¿Fue útil?

Solución

Editar: volver a trabajar en toda la publicación para cubrir lo básico también.

Background.h :

#ifndef BACKGROUND_H
#define BACKGROUND_H

#include <QThread>
#include <QObject>

class Background : public QThread 
{
Q_OBJECT
public:
   Background(QObject* parent = 0):QThread(parent){}
protected:
   void run()
   {
      qDebug(qPrintable(QString("Child function ran in thread: %1").arg(QThread::currentThreadId())));
   }
};

class BackgroundConcurrent : public QObject
{
Q_OBJECT
public:
   BackgroundConcurrent(QObject* parent = 0):QObject(parent){}
public slots:
   void doWork() const
   {
      qDebug(qPrintable(QString("Concurrent child function ran in thread: %1").arg(QThread::currentThreadId())));
   }
};

class BackgroundTrigger : public QObject
{
Q_OBJECT
public:
   BackgroundTrigger(QObject* parent = 0):QObject(parent){}
   ~BackgroundTrigger()
   {
      foreach(QObject* child, children())
      {
         QThread* childThread = qobject_cast<QThread*>(child);
         if (childThread)
            childThread->wait();
      }
   }
public slots:
   void triggerWorker()
   {
      Background* child = new Background(this);
      child->start();
   }
};

#endif // BACKGROUND_H

main.cpp :

#include "Background.h"

#include <QCoreApplication>
#include <QtConcurrentRun>

int main(int argc, char *argv[])  
{   
QCoreApplication a(argc, argv);   

// Using QThread
BackgroundTrigger childTrigger;
qDebug(qPrintable(QString("Main function ran in thread: %1").arg(QThread::currentThreadId())));

// Call child
childTrigger.triggerWorker();
childTrigger.triggerWorker();

// Using QtConcurrent
BackgroundConcurrent cchild;
QFuture<void> future1 = QtConcurrent::run(&cchild, &BackgroundConcurrent::doWork);
QFuture<void> future2 = QtConcurrent::run(&cchild, &BackgroundConcurrent::doWork);

return 0;
}

Salida de muestra:

Main function ran in thread: 1087038064
Child function ran in thread: 1091267472
Child function ran in thread: 1093417872
Concurrent child function ran in thread: 1095519120
Concurrent child function ran in thread: 1097644944

Asegúrese de ejecutar moc en sus archivos de encabezado, qmake y < a href = "http://www.cmake.org/cmake/help/documentation.html" rel = "nofollow noreferrer"> cmake ambos admiten la creación de tus makefiles.

Aquí está el archivo CMakeLists.txt que utilicé para construir el código:

cmake_minimum_required(VERSION 2.6)

#Project name
project(TEST)

#Use Qt4
find_package(Qt4)

if(QT4_FOUND)
set(QT_USE_QTOPENGL TRUE)
include(${QT_USE_FILE})

set(LIBS
    ${QT_LIBRARIES}
    )

#Source files (*.cpp, *.o)
set(TEST_SRCS main.cpp)

#Header files (*.h[pp])
set(TEST_HDRS Background.h)

#Qt macros to handle uic, moc, etc...
QT4_WRAP_CPP(TEST_MOC ${TEST_HDRS} OPTIONS -nw)

set(TEST_ALLSRC ${TEST_SRCS} ${TEST_MOC})

#Create main
add_executable(test ${TEST_ALLSRC})
target_link_libraries(test ${LIBS})

endif(QT4_FOUND)

Otros consejos

En realidad, su solución actual al problema es un buen truco.

Si prefieres hacerlo en un " limpiador " moda, debes iniciar un bucle de evento en tu hilo de trabajador. Entonces, el subproceso de trabajo podrá recibir señales del subproceso principal. Puede llamar a una función en el subproceso secundario (mediante el mecanismo de señal / ranura) desde el subproceso principal para activar la operación.

Vea aquí para más detalles: http://doc.trolltech.com/4.2/threads. html # per-thread-event-loop

(Sugerencia: la idea clave es que crees el objeto de recepción en el subproceso de trabajo; luego, sus ranuras se procesarán en ese subproceso; o podrías usar la función MoveToThread ())

Parece que es posible que desee utilizar una señal para eso, para adaptarse al estilo Qt normal. Consulte esta pregunta ; La respuesta aceptada parece coincidir con tu pregunta también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top