Results 1 to 6 of 6

Thread: QThread Proper Use ?? connect Problems....

  1. #1
    Join Date
    Feb 2016
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default QThread Proper Use ?? connect Problems....

    Hi everyone,

    I'm new on this forum. I'm using Qt4.8.6 for its GUI performances but now I want to use QThreads properly. I saw on the web different ways to declare and use them.

    - redefinition of methods run() of Object inheriting of QThread class => Wrong way

    - definition of a Worker and worker->moveToThread (QThread*) => Right way ??? (https://forum.qt.io/topic/14378/my-t...y-use-qthreads)

    I developed a small project with these two methods to compare them. threadA which displays "A" and threadB which displays "B". To start/stop each threads, there are buttons. Both of these methods work (displaying AAAAA when AButton pushed, BBBBBBB when BButton pushed and ABABABABABA when both are pushed...

    BUT if I follow steps of the second method (Correct use), I must connect :
    Qt Code:
    1. connect(thread, SIGNAL(started()), worker, SLOT(process())); OK
    2. connect(worker, SIGNAL(finished()), thread, SLOT(quit())); OK
    To copy to clipboard, switch view to plain text mode 
    but when I add these two connections, I have : Violation of Ox0FFFFFFFF emplacement Mutex....
    Qt Code:
    1. connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    2. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    To copy to clipboard, switch view to plain text mode 
    How can I do to make this error disappear ?
    Other question, in my code when i'm displaying threadID, it always displays 00000000159 (for example), for both threads ! I think I'm missing something.... Thread must NOT have the same ID ???? principles ??? (same problem in the two methods)

    this is my code, without hpp files :
    -------------------------------------------
    Worker.cpp
    Qt Code:
    1. Worker::Worker() { stopped = false;} // attribute of Worker instance
    2.  
    3. void Worker::process()
    4. {
    5. while (!stopped)
    6. std::cout << messageStr.toStdString(); // attribute of Worker instance
    7. emit finished();
    8. }
    9.  
    10. void Worker::stop() { stopped = true;}
    11. void Worker::start() {stopped = false;}
    To copy to clipboard, switch view to plain text mode 
    ---------------------------------------------
    ThreadDialog.cpp
    Qt Code:
    1. ThreadDialog::ThreadDialog(QWidget *parent) : QDialog(parent)
    2. {
    3. workerA = new Worker();
    4. workerB = new Worker();
    5.  
    6. threadAButton = new QPushButton(tr("Start A"));
    7. threadBButton = new QPushButton(tr("Start B"));
    8. quitButton = new QPushButton(tr("Quit"));
    9. quitButton->setDefault(true);
    10.  
    11. threadA = new QThread;
    12. workerA->setMessage("A ");
    13. workerA->moveToThread(threadA);
    14.  
    15. threadB = new QThread;
    16. workerB->setMessage("B ");
    17. workerB->moveToThread(threadB);
    18.  
    19. connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
    20. connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
    21. //connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
    22. //connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
    23.  
    24. connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
    25. connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
    26. //connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
    27. //connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
    28.  
    29. connect(threadAButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadA()));
    30. connect(threadBButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadB()));
    31. connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
    32. .... // displayLayout
    33. }
    34.  
    35. void ThreadDialog::startOrStopThreadA()
    36. {
    37. if (threadA->isRunning())
    38. {
    39. workerA->stop();
    40. threadAButton->setText(tr("Start A"));
    41. }
    42. else
    43. {
    44. std::cout << threadA->currentThreadId() << std::endl;
    45. workerA->start();
    46. threadA->start();
    47. threadAButton->setText(tr("Stop A"));
    48. }
    49. }
    50.  
    51. void ThreadDialog::startOrStopThreadB()
    52. {
    53. if (threadB->isRunning())
    54. {
    55. workerB->stop();
    56. threadBButton->setText(tr("Start B"));
    57. }
    58. else
    59. {
    60. std::cout << threadB->currentThreadId() << std::endl;
    61. workerB->start();
    62. threadB->start();
    63. threadBButton->setText(tr("Stop B"));
    64. }
    65. }
    66.  
    67. void ThreadDialog::closeEvent(QCloseEvent *event)
    68. {
    69. workerA->stop();
    70. workerB->stop();
    71. threadA->wait();
    72. threadB->wait();
    73. threadA->exit();
    74. threadB->exit();
    75.  
    76. event->accept();
    77. }
    To copy to clipboard, switch view to plain text mode 
    Please Help me to understand QThread features...
    Thank you

    GuiHanoi
    Last edited by anda_skoa; 23rd February 2016 at 10:29. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,356
    Thanks
    36
    Thanked 1,533 Times in 1,484 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QThread Proper Use ?? connect Problems....

    Quote Originally Posted by GuiHanoi View Post
    - redefinition of methods run() of Object inheriting of QThread class => Wrong way

    - definition of a Worker and worker->moveToThread (QThread*) => Right way ??? (https://forum.qt.io/topic/14378/my-t...y-use-qthreads)
    Both options are OK, it depends on what the thread does.
    The first is the better option for something that is a single, long operation, the second is a good option for things that need events while processing.

    Quote Originally Posted by GuiHanoi View Post
    I developed a small project with these two methods to compare them. threadA which displays "A" and threadB which displays "B". To start/stop each threads, there are buttons. Both of these methods work (displaying AAAAA when AButton pushed, BBBBBBB when BButton pushed and ABABABABABA when both are pushed...
    I personally would chose option 1 for that, way easier IMHO.

    Quote Originally Posted by GuiHanoi View Post
    but when I add these two connections, I have : Violation of Ox0FFFFFFFF emplacement Mutex....
    Qt Code:
    1. connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    2. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    To copy to clipboard, switch view to plain text mode 
    At which of the two connects to you get the error?
    It looks fine.

    Quote Originally Posted by GuiHanoi View Post
    Other question, in my code when i'm displaying threadID, it always displays 00000000159 (for example), for both threads ! I think I'm missing something.... Thread must NOT have the same ID ???? principles ??? (same problem in the two methods)
    Your worker code does not output any thread ID, you only ever write the main thread's ID in the dialog code.

    Quote Originally Posted by GuiHanoi View Post
    Worker.cpp
    Qt Code:
    1. Worker::Worker() { stopped = false;} // attribute of Worker instance
    2.  
    3. void Worker::process()
    4. {
    5. while (!stopped)
    6. std::cout << messageStr.toStdString(); // attribute of Worker instance
    7. emit finished();
    8. }
    9.  
    10. void Worker::stop() { stopped = true;}
    11. void Worker::start() {stopped = false;}
    To copy to clipboard, switch view to plain text mode 
    Concurrent access to members by multiple threads needs to be serialized, e.g. by using a mutex.
    Here that is the access to "stopped", which is accessed by the worker thread in process() and by the main thread in stop() and start().

    Quote Originally Posted by GuiHanoi View Post
    Qt Code:
    1. void ThreadDialog::closeEvent(QCloseEvent *event)
    2. {
    3. workerA->stop();
    4. workerB->stop();
    5. threadA->wait();
    6. threadB->wait();
    7. threadA->exit();
    8. threadB->exit();
    9.  
    10. event->accept();
    11. }
    To copy to clipboard, switch view to plain text mode 
    QThread::exit() doesn't make much sense here. When wait() returns the thread has already exited.

    Cheers,
    _

  3. #3
    Join Date
    Feb 2016
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread Proper Use ?? connect Problems....

    Hi,

    Thank you for your fast but helpful answer !

    In my case, I have to display camera data stream (for visualization) into a QLabel but still use GUI (buttons or process, etc.). So I heard you well, I have to choose the second option. (Currently, I had implemented the first method in my solution, but I noticed that it has low performance (200 to 300ms refreshing cycle however camera has only 50ms exposure time...) but didn't crash. So I thought that I was mistaken somewhere.

    if I only write : connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater());
    When I click on start button, it displays A correctly, and when I click on Stop button, it stops displaying A. OK Correct functionality
    But when I click one again on start button, I have an Exception HeapAlloc (malloc.c).

    if I only write : connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater());
    Correct functionality until I click once again on start button : Ecxeption 5DB3CCAE (QtCored4.dll), emplacement Violation (qmutex.cpp) QMutex::lock()

    If I'm writing these two lines : same error QMutex::lock()

    I thought that because of my TWO Worker declarations, I didn't have to put Mutex protection. Why do I have to do that ? because "stopped" member is not shared with threadA and B because there are two Workers... ??

    So I wrote QThread::currentThreadId() in Worker process method and Yes I have now several ID numbers of thread, but each time a different. :s I thought that there were my two threads that were doing the action and so I had thought I would only see two ID numbers.. maybe because of this line : connect(worker, SIGNAL(finished()), thread, SLOT(quit()) ????

    Ok for the dispensable exit() !

    Thank you
    Thanks

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,356
    Thanks
    36
    Thanked 1,533 Times in 1,484 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QThread Proper Use ?? connect Problems....

    Quote Originally Posted by GuiHanoi View Post
    In my case, I have to display camera data stream (for visualization) into a QLabel but still use GUI (buttons or process, etc.). So I heard you well, I have to choose the second option.
    If you like that option better, go for it.
    I would be using option one.

    Quote Originally Posted by GuiHanoi View Post
    if I only write : connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater());
    When I click on start button, it displays A correctly, and when I click on Stop button, it stops displaying A. OK Correct functionality
    But when I click one again on start button, I have an Exception HeapAlloc (malloc.c).
    Ah, so the crash does not happen at connect. That was puzzling me.
    That you crash on second start() is understandable, you are calling a method on an invalid pointer (the object got delete).

    Quote Originally Posted by GuiHanoi View Post
    I thought that because of my TWO Worker declarations, I didn't have to put Mutex protection. Why do I have to do that ? because "stopped" member is not shared with threadA and B because there are two Workers... ??
    The member is accessed by the respective worker thread and the main thread.
    Alternatively to implementing that correctly with a mutex, you could also use QThread::isInterruptionRequested() in the loop and QThread::requestInterruption() instead of stop().

    Quote Originally Posted by GuiHanoi View Post
    So I wrote QThread::currentThreadId() in Worker process method and Yes I have now several ID numbers of thread, but each time a different. :s I thought that there were my two threads that were doing the action and so I had thought I would only see two ID numbers.. maybe because of this line : connect(worker, SIGNAL(finished()), thread, SLOT(quit()) ????
    When you call QThread::start() it will get a new thread from the operating system at let it handle run(), which in your case just emits started() and runs process().

    Cheers,
    _

  5. #5
    Join Date
    Feb 2016
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread Proper Use ?? connect Problems....

    Thank you for your answers,

    now I understand better QThread class and its functionality. last question. Is this a problem not to call deleteLater() for a thread ?
    Thanks

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,356
    Thanks
    36
    Thanked 1,533 Times in 1,484 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QThread Proper Use ?? connect Problems....

    If your thread exists for the whole life time of the program, then you don't necessarily have to manually delete it.

    deleteLater() is used here only to remove it once it has finished, but you could also ask it to stop, wait for it to be stopped and then delete it with "delete" or let its QObject parent delete it (as long as you have stopped it before).

    Cheers,
    _

Similar Threads

  1. connect and qthread
    By tom989 in forum Newbie
    Replies: 1
    Last Post: 5th May 2013, 23:56
  2. Trying to get problems with QThread
    By valdemar593 in forum Qt Programming
    Replies: 1
    Last Post: 21st May 2011, 22:26
  3. Problems with a QThread
    By franco.amato in forum Qt Programming
    Replies: 10
    Last Post: 5th April 2010, 10:46
  4. Problems with Threads connect
    By Max123 in forum Qt Programming
    Replies: 3
    Last Post: 29th March 2010, 12:20
  5. Problems with Qsemaphore and QThread
    By perseo in forum Qt Programming
    Replies: 2
    Last Post: 27th August 2008, 01:21

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.