QT Classics-Threading, events and Qobject

Source: Internet
Author: User
Tags socket
Introduction

You ' re doing it wrong. -bradley T. Hughes

Threading is one of the most popular discussion topics in QT Channel. Many people joined the discussion and asked how to solve the problems they encountered when running cross-threading programming.

A quick review of their code, in the problem found, ten encountered the biggest problem is that they used a thread somewhere, and then fell into the trap of parallel programming. The "Ease of use" of creating and running threads in Qt, the lack of relevant programming, especially the knowledge of asynchronous network programming, or the habit of using other toolsets, these factors and the QT signal slot architecture are often used to make people shoot themselves down at their feet. In addition, QT support for threading is a double-edged sword: It feels very simple even if you are doing QT multithreaded programming, but at the same time you have to be especially careful with the new features that Qt adds, especially with Qobject.

The purpose of this article is not to teach you how to use threads, how to lock them properly, or to teach you how to do parallel development or how to write extensible programs, and there are many good books on these topics, such as the list of recommended readings for this link. The purpose of this article is to introduce the event loops and threading usage of QT 4 to readers to help them develop more robust multithreaded code with better structure, and avoid the QT event loops and common mistakes that are used by threads. Prerequisites

Considering that this article is not a general introduction to threading, we hope you have the following knowledge:

C + + Basics, Qt basics: qojbects, signals/slots, event handling, understanding what threads, threads are related to processes, and operating systems; Learn how the main operating system starts, stops, waits, and ends a thread; Learn how to use mutexes, semaphores, and wait Conditions to create a thread safe/reentrant function, data structure, class. In this article we will use the following noun explanations, namely

reentrant A class is called reentrant: as long as there is at most one thread accessing the same instance at the same time, we say that multiple threads can safely use their own instances within the respective thread. A function is called reentrant: if every call to a function accesses only its unique data (the translator notes: Global variables are not exclusive, but shared), then we say that multiple threads can safely call this function. In other words, the consumer of classes and functions must use some external locking mechanism to implement the serialization of accessing an object instance or shared data. Thread Safety If multiple threads can use objects of a class at the same time, then this class is called thread-safe, and if multiple threads can use shared data in a function body at the same time, this function is called thread-safe. (Translator Note: more reentrant (reentrant) and T thread Safety (THREAD-SAFE) explanations: For classes, if all of its member functions can be called simultaneously by different threads without affecting each other-even if the calls are for the same class object, the class is defined as thread-safe. For a class, the class is defined as Reentrant if its different instances can be used concurrently in different threads without affecting each other. In the definition of QT, at the class level, Thread-safe is a stricter requirement than reentrant) event and Event loops

As an event-driven toolset, QT's event and event distribution plays a central role. This article will not discuss this topic comprehensively, but will focus on some key concepts related to threading. To learn more about QT Event Systems See (here [doc.qt.nokia.com] and here [doc.qt.nokia.com]) (Translator Note: Also welcome to the translator's blog: A brief discussion on the event handling mechanism of QT one, two)

A QT event is an object that represents something interesting and has already occurred; The main difference between an event and a signal is that the event is targeted at a specific target object in our application (and this object determines how we handle the event), and the signal launch is "aimless." From the point of view of code, all event instances are subclasses of qevent [doc.qt.nokia.com], and all derived classes of Qobject can overload the virtual function qobject::event () to enable processing of the object instance events.

Events can be generated either inside or outside of the application, such as:

The Qkeyevent and Qmouseevent objects represent interactive events related to the keyboard and mouse, and they come from the Windows Management program. When the timer starts to tick, the Qtimerevent objects are sent to the Qobject object, which often comes from the operating system. When a subclass object is added or deleted, the Qchildevent object is sent to a Qobject object, and they come from within your application. An important thing about events is that they are not distributed immediately when the event is generated, but instead are listed in an event queue Queue), waiting for a later time to be sent. The allocator (dispatcher) traverses the event queue and sends the events that are in the stack to their target objects, so they are called event loops. Conceptually, the next snippet describes the outline of an event loop:

1 2 3 4 5 6 7 1:while (is_active) 2: {3:while (!event_queue_is_empty) 4:dispatch_next_event ();   5:6: Wait_for_more_events (); 7:}

We enter the main event loop of QT by running Qcoreapplication::exec (), which causes blocking until Qcoreapplication::exit () or Qcoreapplication::quit () is called. And then end the loop.

This "wait_for_more_events ()" function blocks until an event is generated. If we think about it, we will find that all entities that generate events at that point in time must be resources from the outside (since all of the current internal event dispatches have ended and there are no pending events waiting to be processed in the event queue), so the event loop is awakened: Window management activities (keyboard keys, mouse clicks, Interaction with Windows, etc.); the socket activity (there is a visible data to read or a writable non-blocking socket, a new socket connection is generated); Timers (that is, the timer starts timing) Other threads post events (see below). In UNIX systems, Windows management activities (that is, X11) notify applications via sockets (Unix domains or TCP/IP), because clients use them to communicate with the X server. If we decide to use an internal socketpair (2) for cross-thread event distribution, then the Windows management activity needs to wake up the sockets; timers;

This is also what *select (2) * System calls do: it monitors a set of descriptors for the Windows Management activity, and it times out if there is no activity for a period of time. What QT wants to do is convert the return value of the system call Select to the correct Qevent subclass object and include it in the stack of event queues, and now you know what's in the event loop:) Why you need to run the event loop.

The following list is not all, but you will have a panorama, and you should be able to guess which classes need to use the event loop. *widgets Drawing and Interaction *: When distributing qpaintevent events, Qwidget::p aintevent () will be called. Qpaintevent can be generated in the internal qwidget::update (), or in external Windows management (for example, a window showing hidden). Similarly, events that correspond to various interactions (keyboards, mice, and so on) require event loops to be distributed. Timers: Long story short, when select (2) or a similar call times out, the timer starts to tick, so you need to let Qt get those calls to work for you by returning the event loop. Networking: So the underlying QT network classes (Qtcpsocket, Qudpsocket, qtcpserver, etc.) are designed to be asynchronous. When you call read (), they simply return the data that is already visible, and when you call write (), they simply include the write operation in the execution schedule to be executed later. True Read and write occurs only when the event loop returns. Note that although the QT network classes provide the appropriate synchronization methods (waitfor*), they are not recommended because they block the waiting event loop. To an upper class like Qnetworkaccessmanager, there is no synchronization API and an event loop is required. Blocking Event Loops

Before we discuss why * you never block the event loop, let's try to figure out what "blocking" means. Suppose you have a button widget that emit a signal when it is pressed, and a worker object that we define below connects this signal, and the slot of the object does a lot of time-consuming things. When you finish clicking this button, the function call stack from the top below looks like this:

1 2 3 4 5 6 7

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.