Mutex applications for multi-thread synchronization on windows, multi-thread mutex

Source: Internet
Author: User

Mutex applications for multi-thread synchronization on windows, multi-thread mutex

Mutex application for multi-thread synchronization on windows

  • Preface
    Thread Composition:

The Zookeeper operating system schedules a certain CPU time for each running thread --Time slice. The system provides a time slice for the thread in a loop mode. The thread runs within its own time, and multiple threads continuously switch and run. Because the time slice is quite short, it gives the user the feeling that, it is as if the thread is running at the same time.
Worker a single cpu computer can run only one thread at a time. If the computer has multiple CPUs, the thread can actually run simultaneously.
On the windows platform, you can use the CreateThread function of the windows api to create a thread. The function declaration is as follows:

WINBASEAPIHANDLEWINAPICreateThread(    LPSECURITY_ATTRIBUTES lpThreadAttributes,    DWORD dwStackSize,    LPTHREAD_START_ROUTINE lpStartAddress,    LPVOID lpParameter,    DWORD dwCreationFlags,    LPDWORD lpThreadId    );
Parameter description:
LpThreadAttributes Thread security. Use the default security. Generally, the default value is null.
DwStackSize Stack size. 0 indicates the default size.
LpStartAddress The function pointer to be executed by the thread, that is, the entry function.
LpParameter Thread Parameters
DwCreationFlags Thread flag. If it is 0, run immediately after creation
LpThreadId LPDWORD is the return value type. It generally transmits the address to receive the identifier of the thread. It is generally set to null.
Because windows api functions are used, they include:
#include <windows.h>
In addition, the standard input and output functions are required, so they include:
#include <iostream.h>
-The issue leads to the issue where ticket sales take multiple ticket sales windows as an example. A Global ticket count tickets is defined and two threads are used to sell tickets. The two threads access the same variable tickets, let's first look at an incorrect statement:
// Problematic program # include <windows. h> # include <iostream. h> dword winapi feature (LPVOID lpParameter); dword winapi Fun2Proc (LPVOID lpParameter); int tickets = 100; 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 ); system ("pause");} dword winapi Fun1Proc (LPVOID lpParameter) {while (TRUE) {if (tickets> 0) {Sleep (1 ); // assume that it is the time cout <"thread1 required ticket:" <tickets -- <endl;} else break;} return 0 ;} dword winapi Fun2Proc (LPVOID lpParameter // thread data) {while (TRUE) {if (tickets> 0) {Sleep (1); cout <"thread2 restart ticket: "<tickets -- <endl;} else break;} return 0 ;}
Sleep (1) in the worker threads; the table name indicates that the thread has no execution permission, and the operating system selects another thread for execution. Therefore, the execution result is:

Execution result


Zookeeper can see that the program is not executed as expected, and the change of tickets is messy. Therefore, when two threads access the same resource, consider Thread SynchronizationProblem: when one of the threads changes the resource, other threads cannot access the resource. They can only wait until the thread finishes executing the task and other threads can access the resource.
Zookeeper is generally used Mutex objectTo synchronize threads.
  • Mutex object
    Features:
    A mutex is a kernel object that ensures that a thread has mutex access to a single resource.
    The Zookeeper mutex object contains a used quantity, a thread ID, and a counter.
    The   ID is used to identify which thread in the system has a mutex object. The counter is used to specify the number of times that the thread has a mutex object.
    The correct example of using mutex objects for multi-thread synchronization in zookeeper is as follows:
# Include <windows. h> # include <iostream. h> dword winapi Fun1Proc (LPVOID lpParameter // thread data); dword winapi Fun2Proc (LPVOID lpParameter/thread data); int index = 0; int tickets = 100; HANDLE hMutex; 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 an anonymous mutex object with a signal. hMutex = CreateMutex (NULL, FALSE, NULL); system ("pause");} dword winapi Fun1Proc (LPVOID lpParameter // thread data) {while (TRUE) {// wait for the signal of the mutex object, INFINITE indicates that the request has been waiting, and the subsequent code is protected by WaitForSingleObject (hMutex, INFINITE); if (tickets> 0) {Sleep (1); cout <"thread1 skip ticket: "<tickets -- <endl;} else break; // release the ownership of the specified mutex object. The operating system sets the thread id of the mutex object to 0, when the mutex object changes to the notified State, thread 2 can request the mutex object ReleaseMutex (hMutex);} return 0;} dword winapi Fun2Proc (LPVOID lpParameter // thread data) {while (TRUE) {WaitForSingleObject (hMutex, INFINITE); if (tickets> 0) {Sleep (1); cout <"thread2 skip ticket: "<tickets -- <endl;} else break; ReleaseMutex (hMutex);} return 0 ;}

Execution result


Zookeeper tests show that the introduction of the mutex object can solve the problem of resource synchronization between threads. The following questions about mutex objects need to be explained.
  • Release of mutex objects
    If the main
    hMutex=CreateMutex(NULL,TRUE,NULL);

Zookeeper sub-thread:

While (TRUE) {ReleaseMutex (hMutex); // invalid // wait for the signal of the mutex object. INFINITE indicates that it has been waiting and future code is protected by WaitForSingleObject (hMutex, INFINITE );}

Required bytes if the second parameter CreateMutex is true, it indicates that the main thread owns the mutex object. The operating system sets the thread id of the mutex object as the main thread id. If the main thread is not released, then the sub-thread will wait, and the sub-thread has no right to release at this time,Therefore, the principle of using mutex objects is: who owns mutex objects and who releases mutex objects.

In addition, if

    hMutex=CreateMutex(NULL,TRUE,NULL);

Merge objects and request mutex again:

    WaitForSingleObject(hMutex,INFINITE);

Merge objects and call to release mutex objects at one time:

    ReleaseMutex(hMutex);

During this time, the sub-thread is still in the waiting state, and the right to use the mutex object is not obtained because:
Optional values CreateMutex (NULL, TRUE, NULL) because the second parameter is true, the main thread has the right to use the mutex object. The internal counter of the mutex object is added with 1. When WaitForSingleObject is called again to request the mutex object,Internal countersAdd another 1. The counter records the number of times the thread has a mutex object, but only releases ReleaseMutex once. The mutex object is still occupied, so the subthread is not authorized.
Therefore, the correct syntax is as follows:

    hMutex=CreateMutex(NULL,TRUE,NULL);    WaitForSingleObject(hMutex,INFINITE);    ReleaseMutex(hMutex);    ReleaseMutex(hMutex);

  If you request mutex object multiple times, you should release the mutex object multiple times.

When zookeeper looks at this situation again, the thread does not release the ownership of mutex objects:

    DWORD WINAPI Fun1Proc(LPVOID lpParameter)    {        waitforsingleobject(hmutex,infinite);        cout<<"thread1 is running"<<endl;        return 0;    }    DWORD WINAPI Fun2Proc(LPVOID lpParameter)    {        waitforsingleobject(hmutex,infinite);        cout<<"thread2 is running"<<endl;        return 0;    }

When zookeeper is executed, the following output is still returned:

    "thread1 is running    "thread2 is running

Zookeeper: If the mutex object is not released when the thread exits, the operating system automatically clears the information of the mutex object occupied by the thread when the thread is destroyed, and the counter returns to zero, in this way, other threads (thread2) can apply for the right to use mutex objects.

  • Create a name mutex object
HMutex = CreateMutex (NULL, TRUE, "myApp"); if (hMutex) {if (ERROR_ALREADY_EXISTS = GetLastError ()) {cout <"an identical application is running! "<Endl; return ;}}

A type of application for naming mutex objects in zookeeper is that only one application instance is running by naming mutex objects.

Zookeeper and above are about the use of mutex objects related to multi-thread synchronization on windows platforms.Event objectFor more information, see. If there are any mistakes in this article, I hope you will not be enlightened.

Copyright Disclaimer: This article is the original author applebite. For more information, see the source.

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.