System API functions for multithreading and thread synchronization

Source: Internet
Author: User
Tags mutex

1. Creation of threads

Must include header file: #include <windows.h>

HANDLE CreateThread (

Lpsecurity_attributes Lpthreadattributes,

DWORD Dwstacksize,

Lpthread_start_routine Lpstartaddress,

LPVOID Lpparameter,

DWORD dwCreationFlags,

Lpdword Lpthreadid

);

Lpthreadattributes: A pointer to the security_attributes struct, which is generally set to NULL, which allows the thread to use default security, and if you want all child processes to inherit the handle of the thread object, you must set a security_ Attributes the struct, initializing its binherithandle member to true;

Dwstacksize: Sets the size of the thread initialization stack, that is, how much address space a thread can use for its own stack, in bytes, and if set to 0, the same stack space size as the thread that called the function;

Lpstartaddress: The starting address of the entry function that points to the new thread;

Lpparameter: Parameters can be passed to the new thread through this parameter, which can be either a numeric value or a pointer to other information;

dwCreationFlags: Sets the additional token for the new thread, and if it is create_suspended, the thread is created and suspended until the ResumeThread function is called by the program, and if 0, the thread runs immediately after it is created;

Lpthreadid: Pointer to a variable that receives the ID of the new thread, which can be null;

Entry functions for new threads:

DWORD WINAPI ThreadProc (LPVOID lpparameter);

threadproc--is the function name of the new thread, which can be changed to a custom thread name;

2. Thread synchronization

There are three ways to synchronize threads: Mutex objects, event objects, critical code Snippets

Comparison:

1. The mutex object and the event object belong to the kernel object, while the kernel object is used for thread synchronization, but the kernel object can be synchronized among the various threads in multiple processes.

2. The key code snippet works in user mode, synchronization is faster, but it is easy to enter a deadlock state when the critical code segment is used, because the timeout value cannot be set while waiting to enter the critical code segment;

  

2.1 Mutex Objects

2.1.1 Using mutex objects for thread synchronization

1) Create Mutex object

HANDLE CreateMutex (

Lpsecurity_attributes Lpmutexattributes,

BOOL Binitialowner,

LPCTSTR lpname

);

Lpmutexattributes: A pointer to the SECURITY_ATTRIBUTES structure, which can be set to NULL, allowing the mutex to use the default security;

Binitialowner: If true, the thread that created the mutex obtains ownership of the object, and if False, the thread does not have ownership of the mutex object that was created;

Lpname: Specifies the name of the mutex and, if NULL, creates an anonymous mutex object;

Return value: If the function call succeeds, returns a handle to the mutex that was created, if a named mutex is created, and the named mutex already exists before it is created, the function returns a handle to the mutex that already exists, and the call to the GetLastError function returns ERROR_ already_exists;

2) Request ownership of the mutex object

DWORD WaitForSingleObject (

HANDLE Hhandle,

DWORD dwmilliseconds

);

Hhandle: The handle of the requested object; Once the signal state of the mutex is obtained, the function returns, and if the signal state of the mutex is not obtained, the function waits until the thread pauses;

Dwmilliseconds: Specifies the time interval of the wait, in milliseconds, if the specified time interval has elapsed, the function returns, and if set to 0, the function will test the state of the object and return immediately; If set to infinite, the function waits until the mutex object's signal is returned;

return value:

WAIT_OBJECT_0-The requested object is a signaled state;

Wait_timeout-The specified time interval has elapsed and the requested object has no signal;

Wait_abandoned-The requested object is a mutex object, the thread that previously owned the object does not release the object before it terminates, grants ownership of the object to the current calling thread, and sets the mutex to a signal-free State;

3) Release ownership of the specified object

BOOL ReleaseMutex (HANDLE Hmutex);

Hmutex: A handle to the mutex object that needs to be freed;

Return value: The function call successfully returned a value other than 0, and the call failed to return 0;

Note: The mutex object who has the release, the request several times need to release several times accordingly;

#include  <windows. H> #include  <iostream. H>dword winapi fun1proc (lpvoid lpparameter);   //thread 1 's entry function declaration dword winapi  Fun2proc (lpvoid lpparameter);   //thread 2 's entry function declaration int index=0;int tickets=100; Handle hmutex;void main () {    handle hthread1;     handle hthread2;    //creates a mutex object     hmutex=createmutex (NULL,FALSE, NULL);     //Create thread     hthread1=createthread (null,0,fun1proc,null,0,null) ;     hthread2=createthread (Null,0,fun2proc,null,0,null);     CloseHandle (HTHREAD1);     closehandle (hThread2);     sleep (4000);} Entry function for thread 1 dword winapi fun1proc (lpvoid lpparameter) {    while (1)      {        waitforsingleobject (HMutex,INFINITE), &Nbsp;       if (tickets>0) {             sleep (1);             cout <<  "Thread01 sell ticket:"  << tickets-- <<  endl;        }else{             break;        }         releasemutex (Hmutex);     }    return 0;} Entry function for thread 2 Dword winapi fun2proc (lpvoid lpparameter) {    while (1)      {        waitforsingleobject (HMutex,INFINITE);         if (tickets>0) {             sleep (1); &NBsp;           cout <<  "Thread02  Sell ticket: " << tickets-- <<endl;         }else{            break;         }        releasemutex (HMutex);     }    return 0;}

2.1.2 uses named mutex objects to ensure that only one instance of a program runs

Call the CreateMutex function to create a named mutex, call the GetLastError function to determine its return value, and if it returns ERROR_ALREADY_EXISTS, it indicates that the named mutex already exists. Therefore, it is judged that an instance of the application is running, and if the return is not error_already_exists, it indicates that the mutex is newly created, so it can be judged that the first instance of the application is currently running;

Void main () {    handle hthread1;    handle hthread2;     //Create a named mutex object     hmutex=createmutex (Null,true, "tickets");     if (Hmutex) {        if (error_already_exists ==  GetLastError ()) {            cout <<   "Can only run one instance of a program"  << endl;             return;        }    }     //Creating Thread     hthread1=createthread (null,0,fun1proc,null,0,null);     hthread2=createthread (Null,0,fun2proc,null,0,null);     closehandle (HTHREAD1);     closehandle (hThread2);     waitforsingleobject (Hmutex,infinite);     releasemutex (HMUtex);     releasemutex (Hmutex);     sleep (4000);} 

2.2 Event Object

2.2.1 Using event objects for thread synchronization

1) There are two types of event objects: an Event object that is manually reset, an automatically reset event object;

When a manually reset event object is notified, all threads waiting for the event object become a scheduled thread, and when the thread waits for ownership of the object, it is necessary to call the ResetEvent function to manually set the event object to no signal state, and when the Automatically reset event object is notified, Only one thread in the thread waiting for the event object becomes a scheduled thread, and when the thread waits for ownership of the object, the event object is automatically set to no signal state;

2) Create Event object

HANDLE CreateEvent (

Lpsecurity_attributes Lpeventattributes,

BOOL bManualReset,

BOOL Binitialstate,

LPCTSTR lpname

);

Lpeventattributes: A pointer to the security_attributes struct, and if set to NULL, the default security is used;

bManualReset: If True, creates an event object that is manually reset, or False to create an automatically reset event object;

Binitialstate: Specifies the initial state of the event object, and if true, the event object is initially signaled, and if false, the initial signal state is not signaled;

Lpname: Specifies the name of the event object, or if NULL, an anonymous event object is created;

3) Set Event object state

BOOL SetEvent (HANDLE hevent); Sets the specified event object to a signaled state

Hevent: Specifies the handle of the event object whose state will be set;

Return value: The function call successfully returned a value other than 0, and the call failed to return 0;

4) Reset Event object state

BOOL resetevent (HANDLE hevent); Sets the specified event object to a non-signaled state

Hevent: Specifies the handle of the event object whose state will be reset;

Return value: The function call successfully returned a value other than 0, and the call failed to return 0;

5) Request Event object

DWORD WaitForSingleObject (HANDLE Hhandle, DWORD dwmilliseconds);

#include  <windows. H> #include  <iostream. H>dword winapi fun1proc (lpvoid lpparameter);   //Thread 1 entry function declaration dword winapi  Fun2proc (lpvoid lpparameter);   //thread 2 entry function declaration int tickets=100; Handle g_hevent;void main () {    handle hthread1;     handle hthread2;    //Create an automatically reset event object     g_hevent=createevent (NULL, False,false,null);     setevent (g_hevent);   //set event object to signaled state      //Creating Thread     hthread1=createthread (null,0,fun1proc,null,0,null);     hthread2=createthread (Null,0,fun2proc,null,0,null);     closehandle (HTHREAD1);     closehandle (hThread2);     sleep (4000);     //Close Event object handle     closehandle (g_hevent);} The entry function of thread 1 is dword winapi fun1proc (lpvoid lpparameter) {    while (1)     {        // Request Event Object         waitforsingleobject (g_hevent,infinite);         if (tickets>0) {             sleep (1);            cout  <<  "Thread01 sell ticket:"  << tickets-- << endl;             //when a thread requests an event object that is automatically reset, the event object is set to no signal state              //You must call the SetEvent function to set the event object to a signaled state after the thread access is complete              setevent (g_hevent);         }else{            setevent (g_hevent);             break;        }     }    return 0;} Entry function for thread 2 Dword winapi fun2proc (lpvoid lpparameter) {    while (1)      {        //Request Event Object          waitforsingleobject (G_hevent,infinite);         if ( tickets>0) {            sleep (1);             cout <<  "thread02 sell  Ticket: " << tickets-- << endl;             setevent (g_hevent);        }else{             setevent (G_hevenT);            break;         }    }    return 0;}

2.2.2 Using event objects to ensure that only one instance of a program runs

Call the CreateEvent function to create a named event object, call the GetLastError function to determine its return value, and if it returns ERROR_ALREADY_EXISTS, it indicates that the named event object already exists, so it is determined that an instance of the application is running If the return is not error_already_exists, it indicates that the event object is newly created, so it can be judged that the first instance of the application is currently running;

Void main () {    handle hthread1;    handle hthread2;     //Create an auto-reset named Event object     g_hevent=createevent (Null,false,false, "tickets" );     if (g_hevent) {        if (ERROR_ALREADY_EXISTS  == getlasterror ()) {            cout  <<  "can only run one instance of a program"  << endl;             return;        }    }     setevent (g_hevent);   //set event object to signaled state     //create thread      hthread1=createthread (null,0,fun1proc,null,0,null);     hthread2= CreateThread (Null,0,fun2proc,null,0,null);     closehandle (HTHREAD1);     closehandle (hThread2);   &nbSp; sleep (4000);     //Close Event object handle     closehandle (G_hEvent);} 

2.3 Key Code Snippets

2.3.1 thread synchronization with critical code snippets

The key code snippet, also known as the critical section, works in user mode; it refers to a piece of code that must have exclusive access to certain resources before the code can execute, often taking the part of the code that accesses the same resource in multiple threads as a critical piece of code;

1) creating Critical code Snippets

VOID initializecriticalsection (lpcritical_section lpcriticalsection);

Lpcriticalsection: A pointer to a critical_section struct, used as a return value, constructs an object of the critical_section struct type before calling the function, and then passes the object address to the function;

2) uninstalling critical Code Snippets

VOID deletecriticalsection (lpcritical_section lpcriticalsection);

3) Get ownership of critical code snippets

VOID entercriticalsection (lpcritical_section lpcriticalsection);

The function waits for ownership of the specified critical code segment, and if the ownership is given to the calling thread, the function returns; otherwise the function waits, causing the thread to wait;

4) Release ownership of critical code snippets

VOID leavecriticalsection (lpcritical_section lpcriticalsection);

#include  <windows. H> #include  <iostream. H>dword winapi fun1proc (Lpvoid lpparameter);D Word winapi fun2proc (LPVOID  Lpparameter);int tickets=100; critical_section g_cs;  //defines a critical code snippet object as a Global object Void main () {    handle  Hthread1;    handle hthread2;    hthread1=createthread (NULL,0, Fun1proc,null,0,null);     hthread2=createthread (Null,0,fun2proc,null,0,null);     closehandle (HTHREAD1);     closehandle (hThread2);     // Create critical Code Snippet     initializecriticalsection (&AMP;G_CS);     sleep (4000);     //Unload Critical Code snippet     deletecriticalsection (&AMP;G_CS);}  dword winapi fun1proc (lpvoid lpparameter) {    while (1)      {        //Getting critical codeSection ownership         entercriticalsection (&AMP;G_CS);         sleep (1);         if (tickets>0) {             sleep (1);             cout <<  "Thread01 sell ticket:"  <<  tickets-- << endl;             //release ownership of critical code Snippets              LeaveCriticalSection (&g_cs);        }else{             leavecriticalsection (&g_cs);             break;        }     }    return 0;} Dword winapi fun2proc (lpvoid lpparameter) {    while (1)      {        //get ownership of critical code Snippets          entercriticalsection (&g_cs);         sleep (1);         if (tickets>0) {             sleep (1);            cout  <<  "Thread02 sell ticket:"  << tickets-- << endl;             //release ownership of critical code Snippets              leavecriticalsection (&g_cs);         }else{            leavecriticalsection (&g_cs);             break;         }    }    return 0;}

2.3.2 using critical code snippets in MFC

1. Call the InitializeCriticalSection function in the constructor of the class and call the DeleteCriticalSection function in the destructor of the class;

2. Each time you call the EnterCriticalSection function in the program to gain ownership of the resources in the critical code snippet, be sure to call the LeaveCriticalSection function accordingly to release the ownership, otherwise the waiting thread cannot execute;

System API functions for multithreading and thread synchronization

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.