Implement multiple threads with VC 5
---- Multi-task, multi-process and multi-threaded ---- Windows95 and WindowsNT operating systems support multi-tasking scheduling and processing, thereby providing multi-tasking space. The programmer can control the run of each segment in the application to write high efficiency applications. ---- The so-called multitasking usually includes two categories: multi-process and multi-threaded. The process refers to an application that is running in the system; threads are the basic unit of the system allocated processor time resources, or one unit that is independently executed within the process. For the operating system, its scheduling unit is a thread. One process includes at least one thread, usually referred to as the main thread. A process starts from the execution of the main thread to create one or more additional threads, which is the so-called multi-threshold. ---- Develop multi-threaded applications can take advantage of the Win32API interface function provided by 32-bit Windows environments, which can also utilize the MFC class libraries in VC . Multi-threaded programming is the same in both ways, and users can select the corresponding tool as needed. This article focuses on the MFC class library provided by VC 5, implements multi-threaded schedule, and synchronous multi-tasking features that caused by thread multitasking, and give a routine that implements multi-threaded. ---- MFC-based multi-thread programming ---- 1.mfc supports multi-threaded support ---- MFC class library provides multi-threaded programming support, user programming is more convenient. Importantly, in the case of multi-window threads, the MFC directly provides the design of the user interface thread. ---- MFC distinguishes between two types of threads: auxiliary thread (Workerthread) and user interface threads (User interfaceRead). The auxiliary thread has no messaging mechanism, which is often used to perform the background calculation and maintenance tasks. The MFC provides a message mechanism for user interface threads to handle user input, responding to user generated events and messages. But for Win32's API, these two threads do not differ, it only needs thread startup addresses to start thread execution tasks. A typical application of the user interface thread is the CWINAPP class, which is a derived class for the CWINTHREAD class, providing the main thread of the application, and is responsible for handling the events and messages generated by the user. The CWINTHREAD class is the basic class of the user interface thread, which is used to maintain local data of a particular thread. Because processing threads are dependent on the CWINTHREAD class, all threads using the MFC must be created by the MFC. For example, the thread created by the Run-Time function _BeginThreadex cannot use any MFCAPI. ---- 2. The creation and termination of the auxiliary thread and user interface thread ---- To create a thread, you need to call the function AFXBEGINTHREAD. This function has two versions depending on the parameter overload, respectively corresponds to the auxiliary thread and the user interface thread. Whether it is auxiliary thread or a user interface thread, you need to specify additional parameters to modify priority, stack size, create flags, and security features. Functions AFXBEGINTHREAD returns a pointer to the CWINTHREAD class object. ---- Creating a helper thread relatively simple, just implement control functions and launching threads without having to derive a class from CwinThread. The brief description is as follows: ---- (1) Implement the control function. The control function defines the thread. When entering the function, thread starts; when exiting, the thread is terminated. This control function is declared as follows: ---- UINTMYCONTROLLINGFunction (lpvoidpparam); ---- This parameter is a single precision 32-bit value. The value received by this parameter will pass to the constructor when the thread object is created, and the control function will explain this value in some way. It can be a quantity value, or pointing to a pointer including a plurality of parameters, or even ignored. If the parameter is a structure, it can not only pass the data from the call function to the thread, or can also be transferred from the thread to the call function.
If such structural return data is used, the thread is to be notified when the result is ready; when the function ends, a value of the UINT type should be returned, indicating the reason for the end. Typically, the return 0 indicates that the other values represent different errors, respectively. ---- (2) Start the thread. Create and initialize an object of a CWINTHREAD class by a function AFXBeginThread, start and return the address of the thread, then the thread enters the operating state. ---- How to define a control function and how to use other parts of the program below with a simple code. UINTMyThreadProc (LPVOIDpParam) {CMyObject * pParam pObject = (CMyObject *); if (pObject == NULL || pObject-> IsKindOf (RUNTIME_CLASS (CMyObject))!) Return-1; // // embodied illegal content parameters ...... RETURN0; // Thread successfully end} // Call the thread in the program ... PNewObject = newcmyObject; AFXBEGINTHREAD (MythreadProc, pnewobject); ... ---- Create a user interface thread has two methods. The first method, first derive a class from the CWintread class (Note: Mustlement must be declared and implemented by macro declance_dyncreate; then call the function AFXBEGINTHREAD to create a CWINTHREAD derived object to initialize, start the thread. The second method, first create an object of class CWINTHREAD by constructor, and then start the thread by the programmer call function :: CreateTHRead. Usually the object of the CWINTHREAD class will automatically terminate at the end of the resonance of the thread. If the programmer wants yourself to control, you will need to set M_Bautodelete to False. Thus after the thread termination, the CWINTHREAD class object still exists. At this time, it is necessary to manually delete the CWINTHREAD object. ---- Usually the thread function ends, the thread will terminate itself, and the CWINTHREAD class will complete the end of the thread. If the programmer wants to force the thread in the execution of the thread, you need to call AFXendThread (NexitCode) in the thread, and its parameter is the thread end code. This will terminate the running of the thread and release the resources occupied by the thread. If you terminate the thread from another thread, you must set a communication method between the two threads. If the thread is terminated from the thread, you can also use the Win32 function (CWINTHREAD class does not provide this member function): BoolterMinateThread (Handlehthread, DWordDwexitcode). However, in the actual programming, the use of the function must be cautious, because once the command is issued, the thread will immediately terminate the thread, and the resources occupied by the thread may cause the system to be unstable. ---- If the termination thread is the last thread within the process, the process is also terminated after the thread termination. ---- 3. Processes and threads ---- In the Windows 95 and WindowsNT operating systems, the task is priority, with a total of 32, from 0 to 31, the system runs according to different priority scheduling threads. . Among them: ---- (1) 0 to 15 are common priorities, and the priority of threads can be dynamically changed. The high priority thread is prioritized, and only the high priority thread is not running, the low priority thread is scheduled to run. The thread of the priority is running according to the time of time.
---- (2) 16 ~ 30 is real-time priority, the biggest difference between real-time priority and ordinary priority is that the operation of the same priority process does not follow the time slice, but the thread that runs first control CPU first If it does not actively abandon the control, the same or low priority threads cannot be run. ---- The priority of a thread belongs to a class and then its relative position in this class. The calculation of thread priority can be represented as follows: ---- Thread Priority = Process class Basic priority thread relative priority ---- Idle_Process_Class ---- Normal_Process_Class ---- high_process_class ---- real_time_process_class ---- Thread_Priority_Idle ---- (minimum priority, only in the system free) ---- Thread_Priority_lowest --- -Thread_priority_below_normal ---- thread_priority_normal (default) ---- thread_priority_above_normal ---- thread_priority_highest ---- Thread_Priority_Critical ---- 4. Thread Synchronization ---- Write multi-threaded application The most important question is that the resource synchronization accesses between threads, and if access violations occurs in sharing resources, incorrect results. For example, a thread is updating the content of a structure, and the other thread is attempting to read the structure. As a result, we will not know what the data read is. ---- MFC provides a set of synchronous and synchronous access classes to solve this problem. Among them, synchronous objects include: CsyncObject, Csemaphore, CMutex, CcriticalSECTION, and CEVENT; synchronous access objects include: CMULTILOCK and CSILOCK. ---- Synchronous class to ensure the overall resources of resources when accessing resources. Where CSyncObject is the base class of the other four synchronization, it is not directly used. Signal Synchronization CSEMAPHORE is often used to access a resource in one application (for example, the application allows multiple views to the same document); event synchronization class CEVENT is usually used to access resources in applications Previous application must wait (for example, the data must be obtained from the communication port before the data is written); the mutually exclusive synchronous class CMUTEX and the critical zone synchronization class ccriticalSection is used to ensure that one resource can only have a thread access. The difference between the two is that the former allows multiple applications to use this resource, for example, the resource is in a DLL, and the latter does not allow access to the same resource to be more than the category of the process, and use the critical area The efficiency is relatively high. ---- Synchronous Access class is used to get access to these control resources. The difference between CMULTILOCK and CSILOCK is only to control access to multiple or single resource objects. ---- 5. Usage of synchronization ---- A simple way to solve synchronization issues is to integrate synchronization classes into the shared class, usually we refer to such shared classes as thread security classes. The method of use of synchronization classes will be described below. For example, an application for maintaining a list of connections for an account. The application allows three accounts to be detected in different windows, but only one account can be updated at a time. Once an account is updated, you need to pass the updated data over the network to a data document. ---- 3 synchronization classes will be used in this example. Since the 3 accounts are allowed once, CSEMAPHORE can be used to limit access to 3 window objects. When an account is updated, the application uses ccriticalsection to ensure that there is only one account update at a time.