First, I would like to quote Bruce Eckel's statement: "to understand the concept of a thread, we should use the process-oriented programming idea instead of the object-oriented programming idea ".
Then, the last two sections of code:
1. Code for slot call
// Threadslottest. h # ifndef threadslottest_h # define threadslottest_h # include <qthread> # include <qtimer> # include <iostream> using namespace STD; Class threadslottest: Public qthread {q_objectprivate: qtimer timer; public: // threadslottest () {movetothread (this); timer. set interval (1000); timer. start (); Connect (& timer, signal (timeout (), this, slot (slot1 () ;}// void run () {exec (); // exec will cause the thread to be stuck in this sentence and will not be executed (unless exit or quit is called)} public slots: void slot1 () {cout <"slot1: "<currentthreadid () <Endl ;};# endif // threadslottest_h // main. CPP # include <qtgui/qapplication> # include <iostream> # include "threadslottest. H "using namespace STD; int main (INT argc, char * argv []) {qapplication A (argc, argv); cout <" Main: "<qthread :: currentthreadid () <Endl; threadslottest TST; TST. start (); Return a.exe C ();}
2. Code without slot calls
// Threadslottest. h # ifndef threadslottest_h # define threadslottest_h # include <qthread> # include <qtimer> # include <iostream> using namespace STD; Class threadslottest: Public qthread {q_objectprivate: qtimer timer; public: // threadslottest () {movetothread (this); timer. set interval (1000); timer. start (); Connect (& timer, signal (timeout (), this, slot (slot1 () ;}// void run () {While (true ); // only change this place ~ } Public slots: void slot1 () {cout <"slot1:" <currentthreadid () <Endl ;};# endif/threadslottest_h // main. CPP # include <qtgui/qapplication> # include <iostream> # include "threadslottest. H "using namespace STD; int main (INT argc, char * argv []) {qapplication A (argc, argv); cout <" Main: "<qthread :: currentthreadid () <Endl; threadslottest TST; TST. start (); Return a.exe C ();}
The two pieces of code are only different from the implementation of the run function of threadslottest:
If exec () is called, a slot function call occurs;
If exec () is not called, no slot function is called.
See the description of qthread exec:
Enters the event loop and waits until exit() is called, returning the value that was passed to exit(). The value returned is 0 if exit() is called via quit().It is necessary to call this function to start event handling.
Meaning:
The Exec () function will let the thread enter the event loop until exit () is called. The return value of exec is the real parameter value when exit is called. If exit is called indirectly through quit, so that exec exits, exec returns 0. To enable event processing, you must call the exec function.
That is to say, a slot call occurs because the event processing mechanism is enabled for this thread.
The truth is not that simple!
If you are as curious as I do, you will notice the first sentence in the threadslottest constructor:
moveToThread(this);
Congratulations! You will soon know the truth!
If you comment out this sentence, the two sections of code will be called and the displayed content will be the same!
Why?
1. Why is the slot function in the second code not executed, but the slot function in the first code executed?
Movetothread is a function in qobject. It changes the event processing of this object to the specified thread for execution. If the event processing mechanism is not enabled for this thread, all signals sent to this object will not be executed in the corresponding slot, and exec is the key to enabling the event processing mechanism!
Therefore, the second part of the code will not be executed because the object receiving the signal (that is, the object containing the slot to be executed) is moved to the threadslottest thread, this thread does not enable the event processing mechanism. That is to say, although the timeout signal is sent (emit), the thread where the receiver is located does not receive it (because the event processing mechanism is not enabled ), as a result, the slot function is not called.
Because the first code executes exec, the event processing mechanism is enabled. Therefore, the thread where the receiver of the timeout signal is located will receive and process the signal, the slot function is called.
2. Why are two sections of code executed after movetothread is removed, and the output results are the same?
The above explains the functions of the movetothread function. If movetothread is not executed, the thread where the threadslottest object is located does not change. In the thread where the main function is executed, the event processing mechanism of the thread is:
...QApplication a(argc, argv);...return a.exec();...
Enabled.
Therefore, the timeout signal of qtimer will be sent to qapplication, and then qapplication will call the slot1 slot function. That is to say, the call of the slot function is irrelevant to the threadslottest thread! It doesn't matter if threadslottest enables or does not enable event processing ~
Note: If you observe it carefully, you will find that when the first piece of code outputs the thread number, the thread number output in the main function is different from the thread number output in the slot1 function!
Why? Because movetothread is used! Therefore, the threadslottest thread is responsible for slot1 calls, so it is different from the qapplication thread number!
After movetothread is removed, in the first and second sections of code, the thread numbers in the output main function are the same as those in the slot1 function, this is because the slot1 function initiated by qapplication is called!
No ~
See:
1,Qthread usage
2,Qthread usage
Both are articles by Daniel! Let's worship it together!