Question

J'ai un thread principal qui appelle une fonction de thread enfant à différents moments, mais je ne suis pas sûr que ce soit la bonne façon de le faire dans Qt.What est faux avec le code ci-dessous et à la recherche d'une meilleure alternative

Un thread principal fonctionne à l'infini quand un thread principal libère le verrou que l'enfant effectue un travail.

#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();  
}
Était-ce utile?

La solution

Modifier: retravailler l'intégralité du message afin de couvrir également les bases.

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;
}

Exemple de sortie:

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

Assurez-vous d'exécuter moc sur vos fichiers d'en-tête, qmake et < a href = "http://www.cmake.org/cmake/help/documentation.html" rel = "nofollow noreferrer"> cmake prend en charge la création de vos fichiers makefiles.

Voici le fichier CMakeLists.txt que j'ai utilisé pour construire le code:

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)

Autres conseils

En fait, votre solution actuelle au problème est un très bon bidouillage.

Si vous préférez le faire dans un "nettoyeur" " mode, vous devriez commencer une boucle d’événements dans votre thread de travail. Ensuite, le thread de travail sera capable de recevoir des signaux du thread principal. Vous pouvez appeler une fonction du thread enfant (à l'aide du mécanisme signal / slot) à partir du thread principal pour déclencher l'opération.

Voir ici pour plus de détails: http://doc.trolltech.com/4.2/threads. html # par-thread-event-loop

(Conseil: L'idée principale est de créer l'objet de réception dans le thread de travail; ses emplacements seront alors traités dans ce thread; vous pouvez également utiliser la fonction MoveToThread ())

Il semble que vous souhaitiez utiliser un signal pour cela, afin de s’adapter au style Qt normal. Consultez cette question ; la réponse acceptée semble également correspondre à votre question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top