Results 1 to 10 of 10

Thread: Finishing a thread in QThread

  1. #1
    Join Date
    Apr 2010
    Posts
    20
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Finishing a thread in QThread

    Hello over there.
    I have a couple of threads running on my program. So, i need finish one of them when a click a button.
    I've tried use quit() and exit(), but didn't work. For now, i am setting true to a bool in class Thread that reaches the end of code, but i need another method.
    Thanks all
    Here is code for now
    Qt Code:
    1. #include "thread.h"
    2.  
    3.  
    4. Thread::Thread(QObject *parent, QString strCaminhoOff, QString strCaminhoPP, int ind) : QThread(parent)
    5. {
    6. this->strCaminhoOff = strCaminhoOff;
    7. this->strCaminhoPP = strCaminhoPP;
    8. stop = false;
    9. this->ind = ind;
    10. }
    11.  
    12. void Thread::run()
    13. {
    14. qDebug() << "Executing a new independant thread, GUI is NOT blocked" << ind;
    15. QTime tempo;
    16. tempo.start();
    17. int i;
    18. for(i=0; i<1000000000; i++){
    19. if(stop == false){
    20. i++; i--;
    21. }else break;
    22. }
    23.  
    24. qDebug() << "\n" << i;
    25.  
    26. emit nova(strCaminhoOff, tempo.elapsed(), ind);
    27.  
    28. //exec();
    29. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Finishing a thread in QThread

    If you want to use quit(), you need to have an eventloop in your thread.
    Otherwise, if you really really want to stop a thread no matter what: terminate()

  3. #3
    Join Date
    Apr 2010
    Posts
    20
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Finishing a thread in QThread

    yeah, i know, i've tried use the event loop with exec() and calling quit() or exit() when push the button, but didn't work.
    I've tried terminate() too, but it's very unstable, sometimes crash the program.
    I am doing anything wrong friend?
    thanks

  4. #4
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Finishing a thread in QThread

    Note, too, that calling terminate() is frowned upon. The problem is that it kills the thread immediately - there is no chance for the thread to delete locally allocated memory, close file handles or do any other cleanup that might be necessary. This may or may not be a problem, but it needs careful attention before you go down that road.

    Why is the way you're doing it now - by checking the value of an external variable - bad? This is the approach most well-behaved threads use for premature termination.

  5. #5
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Finishing a thread in QThread

    You start the eventloop when the thread is already finished.
    What happens if you put it at the top of your run() function?

  6. #6
    Join Date
    Apr 2010
    Posts
    20
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Finishing a thread in QThread

    Tbscope
    If i put it at the top, the threads stay on exec(), so do nothing

    SixDegrees
    Cause my thread will not realize this code, it's just to make something for now. Actually, the thread will call another function of the project, when ready. So, if i choose this way, i will need put this "bool stop" in that class and access from there. So, if there's a way to make the thread stop without the variable, it's better for me. Otherwise, i will keep this idea

  7. #7
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Finishing a thread in QThread

    Quote Originally Posted by Tio View Post
    the thread will call another function of the project, when ready. So, if i choose this way, i will need put this "bool stop" in that class and access from there. So, if there's a way to make the thread stop without the variable, it's better for me.
    The thing is, it’s almost always a bad idea to force another thread to stop dead in its tracks... even more so if you don’t design and control the code. As C++ doesn’t provide a clean-up/recovery mechanism for asynchronous exceptions — if anything, it covers its ears and says, “Nan-nah-nah, I can’t hear you!” — it’s both difficult and inadvisable to try to do this if the thread to be halted is coded in C++.

    Unless there is a really compelling reason to do otherwise, you should always think ask the other thread to stop, not force the other thread to stop.

    Quote Originally Posted by Tio View Post
    If i put it at the top, the threads stay on exec(), so do nothing
    If you use the event loop approach, then you have to program the thread as a sequence of events. This actually works quite well, as it allows you to use signals and slots, and QThread::exit(), to communicate; but it requires a bit of re-thinking about how the thread is programmed. You have to program it almost like a GUI thread, in small steps that are initiated in response to messages and don't block for long, except that each step finishes by queuing a message that will start the next step. You prime the event loop by queuing a message that starts the sequence of events.

  8. #8
    Join Date
    Apr 2010
    Posts
    20
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Finishing a thread in QThread

    Coises
    Can you gimme a little example using exec() and quit()?

  9. #9
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Finishing a thread in QThread

    Quote Originally Posted by Tio View Post
    Can you gimme a little example using exec() and quit()?
    background.h:
    Qt Code:
    1. #include <QList>
    2. #include <QThread>
    3.  
    4. class Background : public QThread {
    5. Q_OBJECT;
    6. QList<int> prime;
    7. public:
    8. Background();
    9. void run();
    10. signals:
    11. void gotNextPrime(QString);
    12. void proceed();
    13. private slots:
    14. void getNextPrime();
    15. };
    To copy to clipboard, switch view to plain text mode 
    background.cpp:
    Qt Code:
    1. #include "background.h"
    2.  
    3. Background::Background() {
    4. moveToThread(this);
    5. connect(this, SIGNAL(proceed()), SLOT(getNextPrime()), Qt::QueuedConnection);
    6. prime += 2;
    7. }
    8.  
    9. void Background::run() {
    10. emit proceed();
    11. exec();
    12. }
    13.  
    14. void Background::getNextPrime() {
    15. for (int p = prime.last() + 1;; ++p) for (int i = 0;; ++i) {
    16. int j = prime.at(i);
    17. int k = p / j;
    18. if (p == j * k) break;
    19. if (j < k) continue;
    20. prime += p;
    21. emit gotNextPrime(QString("Prime %1 is %2.").arg(prime.count()).arg(p));
    22. emit proceed();
    23. return;
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 
    mainwindow.h:
    Qt Code:
    1. #include <QGridLayout>
    2. #include <QLabel>
    3. #include <QMainWindow>
    4. #include <QPushButton>
    5. #include <QWidget>
    6. #include "background.h"
    7.  
    8. class MainWindow : public QMainWindow {
    9. Q_OBJECT
    10. public:
    11. MainWindow(QWidget *parent = 0);
    12. private:
    13. QGridLayout *grid;
    14. QWidget *centralWidget;
    15. QLabel *displayLabel;
    16. QPushButton *stopButton;
    17. QPushButton *startButton;
    18. Background *bgnd;
    19. };
    To copy to clipboard, switch view to plain text mode 
    mainwindow.cpp:
    Qt Code:
    1. #include "mainwindow.h"
    2.  
    3. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    4. centralWidget = new QWidget(this);
    5. displayLabel = new QLabel(centralWidget);
    6. displayLabel->setAlignment(Qt::AlignCenter);
    7. displayLabel->setText("Click Start to begin.");
    8. startButton = new QPushButton(centralWidget);
    9. startButton->setText("Start");
    10. stopButton = new QPushButton(centralWidget);
    11. stopButton->setText("Stop");
    12. grid = new QGridLayout(centralWidget);
    13. grid->addWidget(displayLabel, 0, 0, 1, 2);
    14. grid->addWidget(startButton, 1, 0);
    15. grid->addWidget(stopButton, 1, 1);
    16. setCentralWidget(centralWidget);
    17. bgnd = new Background();
    18. connect (startButton, SIGNAL(clicked()), bgnd, SLOT(start()), Qt::DirectConnection);
    19. connect (stopButton, SIGNAL(clicked()), bgnd, SLOT(quit()));
    20. connect (bgnd, SIGNAL(gotNextPrime(QString)), displayLabel, SLOT(setText(QString)));
    21. }
    To copy to clipboard, switch view to plain text mode 
    main.cpp:
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "mainwindow.h"
    3.  
    4. int main(int argc, char *argv[]) {
    5. QApplication a(argc, argv);
    6. MainWindow w;
    7. w.show();
    8. return a.exec();
    9. }
    To copy to clipboard, switch view to plain text mode 

    Note that the connect in the Background constructor must specify Qt::QueuedConnection — otherwise, since the signal and slot are on the same thread, the emit proceed(); would become effectively a recursive call to getNextPrime(); we need it to go through the queue so a quit() can interrupt the sequence.

    The connect for StartButton has to specify Qt::DirectConnection because until bgnd is started, there is no event loop to process a queued connection.

  10. The following user says thank you to Coises for this useful post:

    Tio (2nd June 2010)

  11. #10
    Join Date
    Apr 2010
    Posts
    20
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Finishing a thread in QThread

    Thank you very much Coises, i will see this code and try it
    when i reach a conclusion, i will post here =D
    And thanks to all people that help me until here ^^

Similar Threads

  1. How can I get the thread ID out of QThread
    By Artschi in forum Qt Programming
    Replies: 9
    Last Post: 8th November 2017, 03:27
  2. Qprocess and mpi not finishing
    By Spifffers in forum Qt Programming
    Replies: 10
    Last Post: 2nd April 2016, 18:40
  3. GUI thread blocked using QThread.
    By summer_of_69 in forum Qt Programming
    Replies: 11
    Last Post: 18th May 2009, 09:43
  4. [QThread] ptrace in thread
    By Macok in forum Qt Programming
    Replies: 4
    Last Post: 8th February 2009, 21:00
  5. Replies: 4
    Last Post: 26th June 2008, 18:41

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.