Multi-thread programming in Qt

Source: Internet
Author: User

From: http://blog.sina.com.cn/s/blog_640531380100wg5e.html

QtAs a cross-platform GUI system based on C ++, it can provide users with powerful functions to construct graphical user interfaces. To meet the needs of users to construct a complex graphic interface system,QtProvides a wide rangeMulti-Thread ProgrammingYes. Starting from Version 2.2,QtMainly from the following three aspects:Multi-Thread ProgrammingSupport: 1. Some basic platform-independent Thread classes are constructed; 2. Thread-safe mode for submitting user-defined events; 3. Multiple inter-Thread synchronization mechanisms, such as semaphores and global locks. These provide great convenience for users. However, in some cases, the timer mechanism can be used by Billy
QtMultithreadingThe mechanism is more convenient to implement the required functions, while avoiding the occurrence of unsafe phenomena. This article not onlyQtInMultithreadingThe support mechanism is discussed, and the timer mechanism simulation is also discussed.Multi-Thread Programming.

1. multi-thread programming supported by the system

Different platforms support different methods for Qt multithreading. When you install Qt on a Windows operating system, thread support is an option of the compiler. The mkfiles subdirectory of Qt contains the compilation files of different types of compilers, among them, files with the-mt suffix support multithreading.

In Unix operating systems, thread support is added by adding the-thread option when running the configure script file. The installation process creates an independent library, libqt-mt. To support multi-threaded programming, you must connect to the Library (the link option is-lqt-mt ), instead of connecting to the common Qt Library (-lqt.

In addition, regardless of the platform, you must define the macro QT_THREAD_SUPPORT (that is, add the compilation option-DQT_THREAD_SUPPORT) when adding thread support ). In Windows, this is usually implemented by adding an option in the qconfig. h file. In Unix systems, it is usually added to the Makefile file.

2. Thread classes in QT

In the QT System, the most important thread-related class is the qthread class, which provides various methods to create a new thread and control thread running. The thread starts execution through the qthread: Run () overload function, which is very similar to the Thread class in Java. In the QT System, a GUI main event thread is always running. The main thread obtains events from the window system and distributes them to various components for processing. In the qthread class, there is also a method for submitting an event to an object from a non-main event thread, that is, the qthread: postevent () method, this method provides a thread-safe method in QT.
Event submission process. The submitted event is put into a queue, and the GUI main event thread is awakened and sent to the corresponding object. This process is the same as the normal window system event processing process. It is worth noting that when the event processing process is called, it is called in the main event thread, rather than in the thread that calls the qthread: postevent method. For example, you can force another thread to redraw a specified region from one thread:

  1. Qwidget* Mywidget;
  2. Qthread: postevent (mywidget,NewQpaintevent (qrect (0, 0, 100,100 )));

However, it is not enough to have only one thread class. To compile a program that supports multiple threads, two different threads need to access the shared data mutex. Therefore, QT also provides the qmutex class, when a thread accesses critical data, it needs to be locked. At this time, other threads cannot lock the critical data at the same time until the previous thread releases the critical data. This method can be used to perform atomic operations on critical data.

In addition, some mechanisms are required to wake up a thread in the waiting state under certain circumstances. The qwaitcondition class provides this function. When a specific event occurs, qwaitcondition will wake up all threads waiting for the event or wake up any selected thread.

3. Application of user-defined events in multi-thread programming

In the QT System, many types of events are defined, such as timer events, mouse movement events, keyboard events, and window control events. Generally, events come from the underlying window system. The main event loop function of QT obtains these events from the system event queue, converts them to qevents, and passes them to the corresponding qobjects object.

To meet your needs, the QT System also provides a qcustomevent class for custom events. These custom events can use qthread: postevent () or qapplication :: postevent () is sent to various controls or other qobject instances. The subclass of the qwidget class can easily receive these custom events through the qwidget: customevent () event handler function. Note that the qcustomevent object has a type ID when it is created to define the event type.
The System-defined event type conflict. The id value must be greater than the "user" value in qevent: type of Enumeration type.

The following example shows how to use user-defined event classes in multi-threaded programming.

The userevent class is a user-defined event class, and its event ID is 346798, which obviously does not conflict with the system-defined event type.

  1. ClassUserevent:PublicQcustomevent// User-defined event class {
  2. Public:Userevent (qstringS):Qcustomevent (346798 ),
    SZ (s){;}
  3. QstringSTR ()Const{
  4. ReturnSz;
  5. }
  6. Private:QStringSz;
  7. };

The userthread class is a subclass inherited from the qthread class. In addition to defining related variables and thread control functions, the main thing in this class is to define the thread startup function userthread: Run (), create a user-defined event userevent in this function, and use the postevent function of the qthread class to submit the event to the corresponding receiving object.

  1. ClassUserThread:PublicQThread// User-Defined Thread class {
  2. Public:UserThread (QObject* R,QMutex* M,QWaitCondition
    * C );
  3. QObject* Aggreger;
  4. }
  5. VoidUserThread: run ()// Thread-class startup function, in which a user-defined event is created {
  6. UserEvent*Re=New
    UserEvent (resultstring );
  7. Qthread: postevent (aggreger,Re );
  8. }

The userwidget class is a subclass of the User-Defined qwidget class used to receive custom events. This class uses the slotgo () function to create a new thread Recv (userthread class ), when a Custom Event (ID 346798) is received, the customevent function is used to process the event.

  1. VoidUserwidget: slotgo ()// User-defined control member functions {
  2. Mutex. Lock ();
  3. If(!Recv)
  4. Recv=New
    Userthread (this,& Mutex,& Condition );
  5. Recv-> Start ();Mutex. Unlock ();
  6. }
  7. VoidUserwidget: customevent (qcustomevent* E)// User-defined event processing function {
  8. If(E-> Type () = 346798){
  9. UserEvent*Re=
    (UserEvent*)E;
  10. Newstring=Re-> str ();
  11. }
  12. }

In this example, a new thread userthread is created in the userwidget object. You can use this thread to implement some periodic processing (such as receiving messages sent from the underlying layer ), A user-defined event is submitted once a specific condition is met. When the userwidget object receives the event, it can handle the event as needed. Generally, the userwidget object can normally perform some routine processing without being affected by the underlying message.

4. multi-thread programming using the timer mechanism

To avoid the problem caused by multi-thread programming in the QT System, you can also use the timer mechanism provided by the system to implement similar functions. The timer mechanism serializes concurrent events, simplifies the processing of concurrent events, and avoids thread-safe problems.

In the following example, several objects need to receive messages from the underlying layer (through inter-process communication mechanisms such as socket and FIFO), and messages are randomly received, A Gui main thread is required to receive messages. When a message is received, the main thread initializes the corresponding object to start processing and returns the message. In this way, the main thread can always update the interface display and receive messages from the outside to control multiple objects at the same time; on the other hand, each object must notify the GUI main thread after processing the message. You can use the User-Defined event Method in section 3rd to install an Event Filter in the main thread to capture custom events from each object, then a signal is sent to call a slot function in the main thread.

In addition, you can use the timer mechanism in QT to implement similar functions without worrying about thread-safe. The following is the relevant code:

A timer is created and started in the User-Defined server class, and the timer timeout is associated with reading device file data using the connect function:

  1. Server ::Server (QWidget* Parent):QWidget (parent ){
  2. ReadTimer=NewQTimer (this );
    // Create and start the timer
  3. Connect (readTimer,SIGNAL (timeout ()),This,SLOT (slotReadFile ()));
    // Call the slotReadFile function whenever the timer times out to read the file
  4. ReadTimer-> start (100 );}

The slotreadfile function reads data from the file when the timer times out, and then restarts the Timer:

  1. IntServer: slotReadFile ()//Message reading and processing functions {
  2. ReadTimer-> stop ();// Temporarily stop Timer
  3. Ret=Read (file,
    Buf);// Read the object if (Ret=NULL ){
  4. ReadTimer-& gt; start (100 );// When no new message exists, restart the timer.
  5. Return (-1 );
  6. }Else
  7. Distribute messages to various objects based on the buf content ......;
  8. ReadTimer-& gt; start (100 );// Restart the timer}

In this program, the user-specified device files are read in a round-robin manner, and the information is sent to the corresponding objects according to the read data. You can create a server class in your GUI main thread to help implement the underlying message receiving process. However, you can still handle issues such as interface display. After each object is processed, restart the timer to read the underlying Device File periodically. Of course, this method is suitable for the case where the event processing time of each object is short, and the message frequency from the underlying device is relatively slow. In this case, the above method can fully meet the user's needs, while avoiding complicated problems related to thread concurrency.

Of course, using the timer mechanism to implement multi-threaded programming has certain limitations in some aspects. Further research and discussion is needed on how to implement multi-threaded programming and how to compile code with higher efficiency.

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.