Multithreaded programming under Windows (II)

Source: Internet
Author: User

Classification of Threads 1. There is a message loop thread
    • MFC has a user interface thread that derives a new class from CWinThread as the UI thread class Cuithread, and then calls AfxBeginThread (Runtime_class (Cuithread)) and starts the thread. The UI thread can create modal dialogs directly without worrying about message loops because the UI thread defaults to a message loop.
    • MFC non-user interface threads, you cannot create modal dialogs, but you can create non-modal dialog boxes or normal Windows, but you must write your own message loops.

  

msg msg;  while 0 0 )    {     translatemessage (&msg);      DispatchMessage (&msg);  }

2. No message loop thread
    • Worker threads in MFC
    • Other normal threads that do not have a message loop.

Communication between Threads 1. Shared Memory variables

Because threads are shared process memory, the most efficient communication is through global/static variables. Parameters need to consider whether to add volitile.

L pass parameters, such as references and pointers. Parameters need to consider whether to add volitile.

2. Message notification
    • If a child thread communicates to the main thread because the main thread has a message loop, the child thread can communicate to the main thread by sending a message. The coupling of global variables can be avoided by using message communication.

The SendMessage must wait for the message function processing to complete before returning, and PostMessage directly into the message queue to return immediately. So the message parameter of SendMessage can be a temporary variable, and the message parameter of PostMessage must guarantee enough lifetime.

    • If a child line threads a custom message loop, you can also specify thread communication through PostThreadMessage.

 while (true)         {            if(GetMessage (&msg,0,0,0//get Msgfrom message Queue            {                switch(msg.message)                    {                     case  My_msg://  Todo:break                ;                    }             }         ;

3. Other ways
    • All cross-process communication methods, of course, can be used across threads.

State 1 between threads. Asynchronous

That is, multiple threads are independent of each other and are unaffected by external threads. The thread itself is a way to implement Asynchrony.

2. Synchronization

That is, multiple threads depend on each other, and thread a evaluates to the premise of thread B's calculation, which means that you must wait for thread A to calculate before starting the calculation of thread B.

3. Mutex

That is, when multiple threads operate on the same resource, one thread must wait for the other thread to finish before proceeding. Mutual exclusion differs from synchronization in that mutual exclusion does not have a succession relationship. The same resource can refer to a global variable or to a file object or other kernel object. Because kernel objects are cross-process, they are more cross-threading.

Wait for function 1. Concept

The WaitForSingleObject function is to wait for the kernel object to return from no signal state to signaled state or timeout. That is, there is no signal state when waiting, there is a signal or timeout to return immediately.

The Waitformulitpleobjects function is to wait for multiple kernel objects to return from a signal-free state to a signaled state or a timeout (which can indicate all objects or any object).

Windows has several kernel objects that can be in the notification and non-notification states: Processes, threads, jobs, files, console input/output/error streams, events, wait timers, semaphores, mutex objects.

2. Wait for the relationship between the function and the kernel object

Object

No signal status

There is a signal status

Successful waiting for side effects

Process

When process activity

When the process terminates

No

Thread

When thread activity

When a thread terminates

No

File

When I/O requests are being processed

At the end of the I/O request

No

Console input

There is no input

When input is present

No

File modification Notification

No file modification notifications

When file system Discovery is modified

Reset Notifications

Automatic Reset Events

ResetEvent, PulseEvent or waiting for success

When you call SetEvent or pulseevnet

Resetting events

Manual reset Event

ResetEvent, or PulseEvent

When you call SetEvent or pulseevnet

No

Auto Reset Timer

Cancelwaitabletimer or waiting for success

When time is up (SetWaitableTimer)

Reset Timer

Manual Reset Timer

Cancelwaitabletimer

When time is up (SetWaitableTimer)

No

Signal Volume

Waiting for success

When the number of resources is >0 (ReleaseSemaphore)

Quantity minus 1

Mutex Amount

Waiting for success

When not owned by a thread (ReleaseMutex)

Get thread ownership

The threads and processes are created and run without a signal state and become signaled when the end runs.

L automatically resets the event (FALSE) object, which is changed to a signal-free state when it waits for success.

The L semaphore object, when called ReleaseSemaphore (quantity plus 1), is in a signaled state, WaitForSingleObject is triggered and the number of signals is immediately reduced by 1.

Advantages and disadvantages of user mode and kernel mode 1. User mode

Advantage: Thread synchronization mechanism is fast

Cons: Easy to get into a deadlock state a problem occurs with thread synchronization between multiple processes. (such as competing resources, deadlocks)

2. Kernel mode

Pros: Support for thread synchronization between multiple processes to prevent deadlocks

Disadvantage: The thread synchronization mechanism is slow and the thread must switch from user mode to kernel mode. This conversion takes a lot of cost: a round trip needs to occupy about 1 0 0 0 C P u cycles on the X 8 6 platform.

State processing between Threads 1. The asynchronous thread

Because the thread itself is asynchronous.

2. Synchronization of Threads

Thread synchronization is primarily through the event kernel object, semaphore (Semaphore) kernel object, and mutex (mutex) kernel objects. Because they are all kernel objects, you can not only operate across threads, but also synchronize across processes.

1. Synchronization of Threads

Thread synchronization is primarily through the event kernel object, semaphore (Semaphore) kernel object, and mutex (mutex) kernel objects. Because they are all kernel objects, you can not only operate across threads, but also synchronize across processes.

Events (Event) Kernel Objects

There are two types of events: Manual reset events and auto-reset events, which need to be manually called ResetEvent after triggering WaitForSingleObject to set the event to no signal , and the latter automatically sets the event to no signal state after triggering waitforsingleobject.

Common functions:

CreateEvent, create the event object.

OpenEvent, opens an event object that has already been created and can be opened across processes.

SetEvent, set the event object to a signaled state.

ResetEvent, set the event object to no signal state.

PulseEvent, the event object is set to a signaled state and then set to a no-signal state, which is not commonly used.

handelg_hevent;intMain () {g_hevent=CreateEvent (null, TRUE, FALSE, null); _beginthreadex (NULL,0, THREADFUN1,0); _beginthreadex (NULL,0, ThreadFun2,0); Setevnet (g_hevent);//}dword WINAPIThreadFun1 (PVOID pparam) {WaitForSingleObject (g_hevent);//Todo ...SetEvent (g_hevnet);return 0;} DWORD WINAPIThreadFun2 (PVOID pparam) {WaitForSingleObject (g_hevent);//Todo ...SetEvent (g_hevnet);return 0;}

Note: If you create a manual reset event above, the two thread functions will execute. If the event is automatically reset, only one thread can be executed, and there is no guarantee which thread will execute first. If you want to ensure that a thread executes first, you can add an event object to ensure that the specified thread has been executed and that the thread has been executed without the order of the Code.

2. Semaphore (Semaphore) Kernel object

Usage rules for semaphores:

The current semaphore resource number is greater than 0 and is marked as signaled.

The current semaphore resource number is 0 and is marked as no signal state.

The semaphore resource number cannot be negative, and the maximum number cannot exceed the specified quantity.

Common functions:

CreateSemaphore, creates a semaphore object.

OpenSemaphore, opens the specified semaphore object, which can be cross-process.

Releasesemaphoer, resource calculation plus 1.

handelg_hsema[2];intMain () {g_hsema[0] =createsemaphore (NULL,1,1, NULL); g_hsema[1] =createsemaphore (NULL,0,1, NULL); _beginthreadex (NULL,0, THREADFUN1,0); _beginthreadex (NULL,0, ThreadFun2,0);} DWORD WINAPIThreadFun1 (PVOID pparam) {WaitForSingleObject (g_hsema[0]);//Todo ...Releasesemaphoer (g_hsema[1]);return 0;} DWORD WINAPIThreadFun2 (PVOID pparam) {WaitForSingleObject (g_hsema[1]);//Todo ...Releasesemaphoer (g_hsema[0]);return 0;}

This ensures that the THREADFUN1 executes, executes the ThreadFun2, and then executes the THREADFUN1, and guarantees that each thread function can only be called once.

3. Mutex (mutex) kernel object

The mutex kernel object ensures that the thread has exclusive access to a single resource. In behavioral characteristics, the mutex is the same as the critical section. However, the mutex is a kernel object, and it is time consuming to switch from user mode to kernel mode. But because it is a kernel object, the mutex is able to cross the process and can set the timeout time, which is more flexible than the critical section.

Common functions:

CreateMutex, creates a mutex object.

OpenMutex, which opens a specified mutex object, can be cross-process.

ReleaseMutex, releasing the mutex, the object is marked as signaled, and the WaitForSingleObject is triggered.

A mutex is like a critical section, with the notion that the current mutex and the current critical section are freed only by the current thread, and that other threads are not freed. Because the mutex is a kernel object, if the thread has terminated, but the mutex it belongs to is still not released, the kernel manager is automatically freed. The critical section does not have this function because the critical section is not a kernel object, so a critical section can cause a deadlock if it is not properly disposed.

Handlecreatemutex (Lpsecurity_attributeslpmutexattributes,

BOOL Binitialowner, LPCTSTR lpname);

Whether the Binitialowner tag owns thread ownership by the creation thread, true indicates that the creator owns, false means that the creator does not own, then the first thread that calls WaitForSingleObject gets thread ownership.

Handelg_hmutex;intMain () {G_hmutex=CreateMutex (Null,false); _beginthreadex (NULL,0, THREADFUN1,0); _beginthreadex (NULL,0, ThreadFun2,0);} DWORD WINAPIThreadFun1 (PVOID pparam) {WaitForSingleObject (G_hmutex);//Todo ...ReleaseMutex (G_hmutex);return 0;} DWORD WINAPIThreadFun2 (PVOID pparam) {WaitForSingleObject (G_hmutex);//Todo ...ReleaseMutex (G_hmutex);return 0;}

Two functions who first call, who gets thread ownership. If you want to specify that the thread run first, you need to determine that the specified thread has already executed and then create a new thread, and you cannot rely on the thread's code creation sequence.

3. Mutual exclusion of threads

Like mutex objects can also achieve mutually exclusive effect, but the mutex is richer, and if it is a simple resource mutex, the use of the critical section is more efficient.

A critical section (Critical) is a piece of code that is accessed exclusively by threads, which means that if a thread is accessing the snippet, the other thread wants to access it, only to wait for the current thread to leave the snippet before it can enter, which ensures thread safety. He works at the user level (relative to the kernel level) and critical_section the critical area correlation mechanism in the window System.

Common functions:

Voidinitializecriticalsection (lpcritical_section lpcriticalsection)//Initialize critical section

Voidentercriticalsection (lpcritical_section lpcriticalsection)//Enter the critical section

Voidleavecriticalsection (lpcritical_section lpcriticalsection)//Exit critical section

Voiddeletecriticalsection (lpcritical_section lpcriticalsection)//release Critical Zone resources

Because the critical section has the concept of thread ownership, the line friend into the critical section has the right to release the critical section. Because the current thread must enter and release, more often, the critical section is used in a function, in order to ensure that there is no release due to the intermediate exit function, we can ensure the release in the following way.

classMutex { Public: Mutex () {initializecriticalsection (section);} ~Mutex () {deletecriticalsection (section);} voidEnter () {entercriticalsection (section);} voidLeave () {leavecriticalsection (section);} structLock;protected: Mutex (Constmutex&); Mutex&operator=(Constmutex&); critical_section section;}; Structmutex::lock {Mutex&s; Lock (Mutex&s): s (s) {s.enter ();} ~Lock () {S.leave ();}}; DWORD Winapithreadfun (PVOID pparam) {mutex::locklock (Mutex);//Todo ... return 0;}

Attention

1. Note that all kernel objects need to call CloseHandle () at the end.

2. Calling MFC object functions across threads is not secure. Because some functions of an MFC object are associated with TLS, some calls can be faulted. such as UpdateData (), it is best to use the handle to send messages to complete the corresponding function.

Multithreaded programming under Windows (II)

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.