Using Qtimer in a thread that does not turn on the event loop (the Qthread::run function has an event loop, creating threads in the constructor is a very interesting thread usage) good

Source: Internet
Author: User
Tags emit

Introduced

The Qtimer is a QT-band timer class, and the Qtimer runtime is dependent on the event loop, and in a nutshell, Qtimer is not available in a thread that does not turn on the event loop (EXEC () is not called). By analyzing the QT source, it is found that the call to Qtimer::start () only adds a timer object to the system's timer vector table, but the timer is not actually turned on. The timer must be opened after a series of calls starting with processevent (), which will process all the timer objects in the Timer vector table. The processevent () method is also constantly being called in the actual exec ().

Problem

You may encounter a resident thread in a project, run a dead loop that handles transactions, and it is not possible to use Qtimer directly in a dead loop to implement timing functions. My own project is to achieve the serial read and write time-out judgment, so need to use the timer.

Solve

The solution can be found on the web, and it works well, but there are problems. Let's talk about the idea first:

The timer object needs to run in a thread that turns on the event loop, so we can move it to a thread that has the event loop turned on by the Movetothread () method. Very happy, we quickly encapsulated a timer class, containing a Qtimer and Qthread object, directly using the Qthread object is because my QT version is 4.8.3,run () is not a pure virtual function, the event loop is turned on by default. The main code is as follows:

[CPP]View PlainCopyprint?
  1. #ifndef Qcustomtimer_h
  2. #define Qcustomtimer_h
  3. #include <QObject>
  4. #include <QTimer>
  5. #include <QThread>
  6. Class Qcustomtimer: Public qobject
  7. {
  8. Q_object
  9. Public
  10. explicit Qcustomtimer (Qobject *parent = 0);
  11. ~qcustomtimer ();
  12. Private
  13. Qtimer *m_ptimer; //Timer Object
  14. Qthread *m_ptimerthread; //Timer dependent thread
  15. Signals:
  16. void startsignal ( int nMsc); Turn on the timer signal
  17. void Stopsignal (); //Stop timer signal
  18. void TimeOut (); //Timer trigger, external need to connect this signal
  19. void Deletelater (); //Delay removing timer signal
  20. Public Slots:
  21. void OnTimer (); //Object internal timing trigger slot function, trigger signal to external launch timer
  22. Public
  23. void Starttimer ( int nMsc); //Turn on timer
  24. void Stoptimer (); //Off timer
  25. void Deletelater (); //Delay Delete Timer object
  26. };
  27. #endif//Qcustomtimer_h
[CPP]View PlainCopy print?
[CPP]View PlainCopyprint?
  1. #include "Qcustomtimer.h"
  2. Qcustomtimer::qcustomtimer (Qobject *parent):
  3. Qobject (parent)
  4. {
  5. M_ptimer = New Qtimer (0);
  6. M_ptimer->setsingleshot ( true); Single-shot triggering
  7. M_ptimerthread->start ();
  8. M_ptimer->movetothread (M_ptimerthread); //Change the thread on which the timer runs
  9. Connect (M_ptimer, SIGNAL (), this , SLOT (OnTimer ()), Qt::D irectconnection); Timer Event Trigger slot
  10. Connect (this , SIGNAL (startsignal (int)), M_ptimer, SLOT (Start ( int)), qt::blockingqueuedconnection); Connect timer start slot function, not "Direct connect"
  11. Connect (this , SIGNAL (Stopsignal ()), M_ptimer, SLOT (Stop ()), qt::blockingqueuedconnection); Connect timer close slot function, not "Direct Connect"
  12. Connect (this , SIGNAL (Deletelater ()), M_ptimer, SLOT (Deletelater ())); Delete the Timer object that is located in the thread, inserting an event with deferred deletion
  13. }
  14. Qcustomtimer::~qcustomtimer ()
  15. {
  16. Stoptimer ();
  17. Deletelater ();
  18. }
  19. void Qcustomtimer::ontimer ()
  20. {
  21. Emit TimeOut (); //TX Timer trigger Signal
  22. }
  23. void Qcustomtimer::starttimer (int nMsc)
  24. {
  25. Emit startsignal (NMSC); //Shangzi in-thread timer Send on timer signal
  26. }
  27. void Qcustomtimer::stoptimer ()
  28. {
  29. Emit stopsignal (); ///Shangzi timer in thread to send stop timer signal
  30. }
  31. void Qcustomtimer::D eletelater ()
  32. {
  33. Emit Deletelater (); //Shangzi thread's event loop inserts a deferred delete event
  34. }


Actually in the initial use, no problem, the timer triggers normally. However, when Qcustomtimer objects are created and refactored very frequently, problems such as crashes occur. More ashamed, this problem bothers me for a long time, although finally solved the problem, but I still do not know what causes, if there is Daniel know, please you must tell me!!

Here's what the code says:

1. When the Movetothread () method is called, the timer object belongs to the child thread, and if it is released, it will either insert the Deletelater () time-lapse Delete event in the document or the object is freed before the run () function returns. The code above uses pointers, uses the form of member variables without pointers, and I try, the program still crashes.

2. To say a little more, is the program crashes basically a few hours to collapse, the program error "pure virtual function is called", for this clue Google a lot of information, but did not find a response plan.

3. Speculation or in the case of high-frequency use, the timer object and the destruction of the thread object has a problem, and deletelater () can not be resolved.

My solution, in fact, is not rigorous, because I did not pinpoint the bug. I changed the thread object to static, that is, to remove the thread object's destruction, only need to properly deconstruct the timer object, this is Deletelater () has the effect. The code is as follows:

[CPP]View PlainCopy print?
  1. #ifndef Qcustomtimer_h
  2. #define Qcustomtimer_h
  3. #include <QObject>
  4. #include <QTimer>
  5. #include <QThread>
  6. Class Qcustomtimer: Public qobject
  7. {
  8. Q_object
  9. Public
  10. explicit Qcustomtimer (Qobject *parent = 0);
  11. ~qcustomtimer ();
  12. Private
  13. static Qthread *m_ptimerthread; //Timer dependent thread
  14. Qtimer *m_ptimer; //Timer Object
  15. Signals:
  16. void startsignal ( int nMsc); Turn on the timer signal
  17. void Stopsignal (); //Stop timer signal
  18. void TimeOut (); //Timer trigger, external need to connect this signal
  19. void Deletelater (); //Delay removing timer signal
  20. Public Slots:
  21. void OnTimer (); //Object internal timing trigger slot function, trigger signal to external launch timer
  22. Public
  23. void Starttimer ( int nMsc); //Turn on timer
  24. void Stoptimer (); //Off timer
  25. void Deletelater (); //Delay Delete Timer object
  26. };
  27. #endif//Qcustomtimer_h

[CPP]View PlainCopyprint?
  1. #include "Qcustomtimer.h"
  2. Static thread member pointer initialization
  3. qthread* qcustomtimer::m_ptimerthread = NULL;
  4. Qcustomtimer::qcustomtimer (Qobject *parent):
  5. Qobject (parent)
  6. {
  7. if (m_ptimerthread = = NULL)
  8. {
  9. //This decision branch relies on QT to initialize static member pointer variables to NULL, not a good practice
  10. //But if there are other global variables in the project and have dependencies, then it should be the case.
  11. //Ensure that the Qcustomtimer class does not have dependencies with other global variables and can be initialized outside of the class, which is better
  12. M_ptimerthread = new Qthread;
  13. }
  14. M_ptimer = New Qtimer (0);
  15. M_ptimer->setsingleshot ( true); Single-shot triggering
  16. M_ptimerthread->start ();
  17. M_ptimer->movetothread (M_ptimerthread); //Change the thread on which the timer runs
  18. Connect (M_ptimer, SIGNAL (), this , SLOT (OnTimer ()), Qt::D irectconnection); Timer Event Trigger slot
  19. Connect (this , SIGNAL (startsignal (int)), M_ptimer, SLOT (Start ( int)), qt::blockingqueuedconnection); Connect timer start slot function, not "Direct connect"
  20. Connect (this , SIGNAL (Stopsignal ()), M_ptimer, SLOT (Stop ()), qt::blockingqueuedconnection); Connect timer close slot function, not "Direct Connect"
  21. Connect (this , SIGNAL (Deletelater ()), M_ptimer, SLOT (Deletelater ())); Delete the Timer object that is located in the thread, inserting an event with deferred deletion
  22. }
  23. Qcustomtimer::~qcustomtimer ()
  24. {
  25. Stoptimer ();
  26. Deletelater ();
  27. }
  28. void Qcustomtimer::ontimer ()
  29. {
  30. Emit TimeOut (); //TX Timer trigger Signal
  31. }
  32. void Qcustomtimer::starttimer (int nMsc)
  33. {
  34. Emit startsignal (NMSC); //Shangzi in-thread timer Send on timer signal
  35. }
  36. void Qcustomtimer::stoptimer ()
  37. {
  38. Emit stopsignal (); ///Shangzi timer in thread to send stop timer signal
  39. }
  40. void Qcustomtimer::D eletelater ()
  41. {
  42. Emit Deletelater (); //Shangzi thread's event loop inserts a deferred delete event
  43. }


What needs to be explained is the initialization position of the static thread, and my approach is a stopgap, because the other global variables in the project have a dependency on the Timer class, which can only be done. The design pattern still needs to be studied well to avoid these bad designs.

The above is the complete code, if there are bugs or problems, welcome to my message!!

http://blog.csdn.net/u013709994/article/details/22175919

Using Qtimer in a thread that does not turn on the event loop (the Qthread::run function has an event loop, creating threads in the constructor is a very interesting thread usage) good

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.