Windows programming multi-thread Summary

Source: Internet
Author: User
Tags delete key

Methods used for thread mutex include: Atomic lock, criticalsection, mutex ),.

The methods used for thread synchronization include event, semaphore, and timer ).

Atomic lock: we all know that simple I ++ is not an atomic operation. In fact, it is done in several steps internally. In this case, multithreading may cause problems. So we can use atomic locks, but this method has some limitations, that is, it can only be used to perform addition and subtraction of simple data operations, if it involves a complex data structure, then there will be problems.

Interlockedincrement (long volatile * addend );

Interlockeddecrement (long volatile * addend );

Interlockedexchangeadd (long volatile * addend,
Longvalue );

Interlockedexchange (long volatile * target,
Longvalue );

Example:

If no atomic lock is used:

# Include <stdio. h> # include <windows. h> # include <process. h> volatile long g_nlogincount; unsigned int _ stdcall fun (void * ppm); const DWORD thread_num = 50; unsigned int _ stdcall threadfun (void * ppm) {g_nlogincount ++; return 0;} int main () {int num = 20; while (Num --) {g_nlogincount = 0; int I; handle [thread_num]; for (I = 0; I <thread_num; I ++) handle [I] = (handle) _ beginthreadex (null, 0, threadfun, null, 0, null); waitformultipleobjects (thread_num, handle, true, infinite); for (I = 0; I <thread_num; I ++) {closehandle (handle [I]);} printf ("% d threads execute I ++, the result is % d \ n ", thread_num, g_nlogincount);} return 0 ;}

Here, I will explain why we have made several threads and made them so complicated: A WHILE LOOP and a for loop. This is because we cannot create multiple threads at a time. Otherwise, problems may occur, you can try to create 100 threads in sequence, which may cause problems. It seems that up to 64 threads can be created at a time. So this complicated method is used here.

Use of Atomic locks:

unsigned int __stdcall ThreadFun(void *pPM){g_nLoginCount++;InterlockedIncrement(&g_nLoginCount);return 0;}


Criticalsection is usually used when threads are mutually exclusive.

Void
Initializecriticalsection (maid); ----------- initialize Key Areas

Void
Deletecriticalsection (maid section );----------- Delete key areas

Void
Entercriticalsection (maid section );----------- Enter key areasVoid
Leavecriticalsection (maid section );----------- Exit Key Areas

General error:

# Include <stdio. h> # include <process. h> # include <windows. h> long g_nnum; unsigned int _ stdcall fun (void * ppm); const int thread_num = 10; int main () {handle [thread_num]; g_nnum = 0; int I = 0; while (I <thread_num) {handle [I ++] = (handle) _ beginthreadex (null, 0, fun, null, 0, null );} waitformultipleobjects (thread_num, handle, true, infinite); for (I = 0; I <sizeof (handle); I ++) {closehandle (handle [I]);} return 0;} unsigned int _ stdcall fun (void * ppm) {sleep (50); g_nnum ++; sleep (0); printf ("the current count is: % d \ n ", g_nnum); Return 0 ;}

When key areas are used:

CRITICAL_SECTION g_csThreadCode;InitializeCriticalSection(&g_csThreadCode);DeleteCriticalSection(&g_csThreadCode);
Unsigned int _ stdcall fun (void * ppm) {sleep (50); entercriticalsection (& g_csthreadcode); g_nnum ++; sleep (0); printf ("the current count is: % d \ n ", g_nnum); leavecriticalsection (& g_csthreadcode); Return 0 ;}

Event)

Handlecreateevent (

Lpsecurity_attributeslpeventattributes,

Boolbmanualreset,

Boolbinitialstate,

Lpctstrlpname

); --------- Create an event.

Handleopenevent (

Dworddwdesiredaccess,

Boolbinherithandle,

Lpctstrlpname

); ------------ Open the event

Boolsetevent (handlehevent); ---------- trigger event

Boolresetevent (handlehevent); ----------- set the event to not triggered


Generally, events are divided into two types:Manual location event (true)And the auto-location event (false), which is specified in the second parameter of the createevent function. Their differences are:When setevent is called, all threads waiting for the event to be activatedAfter the setevent is called, only one thread is activated. AutomaticThe reset event does not need to call the resetevent function, because the system will automatically help you set it to not triggered, and the manual reset event also needs to call the resetevent function.


Before presenting events, let's talk about the differences between thread mutex and thread synchronization. In my understanding, thread mutex is equivalent to two writers writing a file at the same time, causing confusion. Thread Synchronization is equivalent to when a reader is reading a file, the confusion caused by writing constantly. In the past, we passed the thread ID. (The main thread writes data and the sub-thread reads data ).
Events Not used:
# Include <stdio. h> # include <process. h> # include <windows. h> long g_nnum; unsigned int _ stdcall fun (void * ppm); const int thread_num = 10; critical_section g_csthreadcode; int main () {initializecriticalsection (& g_csthreadcode ); handle handle [thread_num]; g_nnum = 0; int I = 0; while (I <thread_num) {handle [I ++] = (handle) _ beginthreadex (null, 0, fun, & I, 0, null) ;}waitformultipleobjects (thread_num, handle, true, infinite); for (I = 0; I <sizeof (handle); I ++) {closehandle (handle [I]);} deletecriticalsection (& g_csthreadcode); Return 0;} unsigned int _ stdcall fun (void * ppm) {int nthreadnum = * (int *) ppm; sleep (50); entercriticalsection (& g_csthreadcode); g_nnum ++; sleep (0); printf ("current thread: % d, current count: % d \ n ", nthreadnum, g_nnum); leavecriticalsection (& g_csthreadcode); Return 0 ;}

The thread ID does not meet the requirements ..
Event usage: (Here we use manual event settings, so we need to call resetevent ).

# Include <stdio. h> # include <process. h> # include <windows. h> long g_nnum; unsigned int _ stdcall fun (void * ppm); const int thread_num = 10; handle g_hthreadevent; critical_section g_csthreadcode; int main () {g_hthreadevent = createevent (null, true, false, null); initializecriticalsection (& g_csthreadcode); handle [thread_num]; g_nnum = 0; int I = 0; while (I <thread_num) {handle [I] = (handle) _ beginthreadex (null, 0, fun, & I, 0, null); waitforsingleobject (g_hthreadevent, infinite); resetevent (g_hthreadevent ); I ++;} waitformultipleobjects (thread_num, handle, true, infinite); for (I = 0; I <sizeof (handle); I ++) {closehandle (handle [I]);} closehandle (g_hthreadevent); deletecriticalsection (& g_csthreadcode); Return 0;} unsigned int _ stdcall fun (void * ppm) {int nthreadnum = * (int *) ppm; setevent (g_hthreadevent); sleep (50); entercriticalsection (& g_csthreadcode); g_nnum ++; sleep (0 ); printf ("current thread: % d, current count: % d \ n", nthreadnum, g_nnum); leavecriticalsection (& g_csthreadcode); Return 0 ;}

The thread ID meets the requirements ..

Mutex
# Include <stdio. h> # include <process. h> # include <windows. h> long g_nnum; unsigned int _ stdcall fun (void * ppm); const int thread_num = 10; handle g_mutex; int main () {g_mutex = createmutex (null, false, null); handle [thread_num]; g_nnum = 0; int I = 0; while (I <thread_num) {handle [I ++] = (handle) _ beginthreadex (null, 0, fun, & I, 0, null);} waitformultipleobjects (thread_num, handle, true, infinite); closehandle (g_mutex); for (I = 0; I <thread_num; I ++) closehandle (handle [I]); Return 0;} unsigned int _ stdcall fun (void * ppm) {sleep (50); waitforsingleobject (g_mutex, infinite ); g_nnum ++; sleep (0); printf ("current count: % d \ n", g_nnum); releasemutex (g_mutex); Return 0 ;}

Semaphores (semaphore)

Handle
Createsemaphore (

 
Lpsecurity_attributes l1_maphoreattributes,

 
Long linitialcount,

 
Long lmaximumcount,

 
Lptstr lpname

); ---------------- Create a semaphore

Handle
Opensemaphore (

 
DWORD dwdesiredaccess,

 
Bool binherithandle,

 
Lptstr lpname

); ---------------- Open the semaphore

Bool
Releasesemaphore (

 
Handle hsemaphore,

 
Long lreleasecount,

 
Lplong lppreviouscount

); ------------------ Release the semaphore

Increase of semaphores: releasesemaphore. Semaphore subtraction: waitforsingleobject (..); when a semaphore is requested, if the current semaphore is 0, that is, it is not triggered, then the thread enters the blocking state until the signal value is greater than 0, this function returns, the thread enters the scheduling state, at the same time, the signal value is reduced by one.

Note: The semaphore value cannot be less than 0.

# Include <stdio. h> # include <process. h> # include <windows. h> long g_nnum; unsigned int _ stdcall fun (void * ppm); const int thread_num = 10; handle g_semaphore; critical_section g_criticalsection; int main () {g_semaphore = createsemaphore (null, 0, 1, null); initializecriticalsection (& g_criticalsection); handle [thread_num]; g_nnum = 0; int I = 0; while (I <thread_num) {handle [I] = (handle) _ beginthreadex (null, 0, fun, & I, 0, null); waitforsingleobject (g_semaphore, infinite); ++ I ;} waitformultipleobjects (thread_num, handle, true, infinite); deletecriticalsection (& g_criticalsection); closehandle (g_semaphore); for (I = 0; I <thread_num; I ++) closehandle (handle [I]); Return 0;} unsigned int _ stdcall fun (void * ppm) {int nthreadnum = * (int *) ppm; releasesemaphore (g_semaphore, 1, null); sleep (50); entercriticalsection (& g_criticalsection); ++ g_nnum; sleep (0); printf ("the current thread is: % d, and the current count is: % d \ n ", nthreadnum, g_nnum); leavecriticalsection (& g_criticalsection); Return 0 ;}

Related Article

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.