Thread Synchronization: mutex

Source: Internet
Author: User

Mutex is a simple form of synchronization (called mutex )). The mutex prohibits multiple threads from entering the protected code "critical section" at the same time ). Therefore, at any time, only one thread is allowed to enter such a code protection zone. Any thread must obtain the ownership of the mutex associated with this region before entering the critical section. If another thread has a mutex in the critical section, other threads cannot enter it. These threads must wait until the current main thread releases the mutex (release. When do I need to use mutex? Mutex is used to protect shared variable code, that is, global or static data. Such data must be protected by mutex to prevent damages when multiple threads access the data simultaneously.

 

The createmutex function creates or opens a named or unnamed mutex object.
Handle createmutex (
Lpsecurity_attributes lpmutexattributes, // SD
Bool binitialowner, // initial owner
Lptstr lpname // Object Name
);

Parameters

① Lpmutexattributes is used to set the security descriptor of the mutex object and whether the sub-process inheritance handle is allowed. If the value of lpmutexattributes is null, the handle cannot be inherited.
② Binitialowner indicates whether to set the mutex owner as the call thread.

③ The lpname parameter sets the mutex name. The name is case sensitive and cannot contain "/". The maximum length is max_path. If it is set to null, the mutex is an anonymous object.

If the call is successful, the mutex handle is returned. Otherwise, null is returned. If the lpname is not null and the mutex with the same name before the call has been created, the mutex handle with the same name is returned, when getlasterror is called, error_already_exists is returned, and the binitialowner parameter is ignored.

You can also callOpenmutexOpen the created non-Anonymous mutex. The prototype is as follows:

Handle openmutex (
DWORD dwdesiredaccess,
Bool binherithandle,
Lptstr lpname
);

After mutex is successfully created or opened, you can use wait functions to wait for and obtain the mutex ownership.

Reprinted (changed ):
The practices and features of mutex objects are as follows:
Createmutex () is used to generate a mutex object, and the passed mutex name string is used to distinguish different mutex objects. That is to say, no matter which process/thread, as long as the input parameter number is the same string, the createmutex () return value (hmutex, handle of mutex) points to the same mutex object. This is the same as the event object. However, mutex and event are very different. mutex has the owner concept. If mutex is owned by threada, threada will not stop when waitforsingleobject () is executed, wait_object_0 will be returned immediately, while other threads will stop when waitforsingleobject () is executed until the ownership of mutex is release or time out. How does thread obtain the ownership of mutex? The main features are as follows:

1. When createmutex (byval 0, 1, "mymutex") enters the second parameter data transmission 1, the thread that calls createmutex and the second parameter data transmission 1 will own the mutex. However, if the second parameter is 0, it indicates that no one in createmutex owns the mutex.
2. Attached Description: If the mutex has no owner, the thread of the first call to waitforsingleobject will have the mutex.

As mentioned above, only threads with the mutex will not stop when waitforsingleobject () is executed, and other threads will stop. How can other threads obtain the ownership of the mutex? It is necessary that the thread that originally owns the mutex will give up its ownership with releasemutex. Once the ownership is released, other threads will remain in the waiting state at waitforsingleobject, one thread will immediately obtain the ownership of the mutex (as described in the preceding 2nd point). Therefore, if other threads also execute waitforsingleobject (), it will be in the waiting state. Because waitforsingleobject () causes mutex to be In the unsignal state (different from event ), therefore, we can complete the need for only one thread to update the shared memory at the same time (of course, we all need to use the mutex rules, that is, when we want to update, we need to use waitforsingleobject () to see if mutex can be obtained.
Right .)

Another thing to note is that if a thread has acquired the ownership of mutex and it calls waitforsingleobject ()
For n times, you must use releasemutex for n times to give up the ownership of mutex. This is different from event, and the call to releasemutex by a non-mutex owner does not have any function. Each time a call is made using waitforsingleobject, mutex will add one counter, and releasemutex will successfully subtract one until the mutex counter is 0.

 

Application instance:

# Include <windows. h>

# Include <stdio. h>

# Define threadcount 2

Handle ghmutex;

DWORD winapi writetodatabase (lpvoid );

Void main ()

{

Handle athread [threadcount];

DWORD threadid;

Int I;

// Create a mutex with no initial owner

Ghmutex = createmutex (

Null, // default security attributes

False, // initially not owned

Null); // unnamed mutex

If (ghmutex = NULL)

{

Printf ("createmutex error: % d/N", getlasterror ());

Return;

}

// Create worker threads

For (I = 0; I <threadcount; I ++)

{

Athread [I] = createthread (

Null, // default security attributes

0, // default stack size

(Lpthread_start_routine) writetodatabase,

Null, // no thread function arguments

0, // default creation flags

& Threadid); // receive thread identifier

If (athread [I] = NULL)

{

Printf ("createthread error: % d/N", getlasterror ());

Return;

}

}

// Wait for all threads to terminate

Waitformultipleobjects (threadcount, athread, true, infinite );

// Close thread and mutex handles

For (I = 0; I <threadcount; I ++)

Closehandle (athread [I]);

Closehandle (ghmutex );

}

DWORD winapi writetodatabase (lpvoid lpparam)

{

DWORD dwcount = 0, dwwaitresult;

// Request ownership of mutex.

While (dwcount <20)

{

Dwwaitresult = waitforsingleobject (

Ghmutex, // handle to mutex

Infinite); // no time-out interval

Switch (dwwaitresult)

{

// The thread got ownership of the mutex

Case wait_object_0:

_ Try {

// Todo: Write to the database

Printf ("thread % d writing to database.../N ",

Getcurrentthreadid ());

Dwcount ++;

}

_ Finally {

// Release ownership of the mutex object

If (! Releasemutex (ghmutex ))

{

// Handle error.

}

}

Break;

// The thread got ownership of an abandoned mutex

// The database is in an indeterminate state

Case wait_abandoned:

Return false;

}

}

Return true;

}

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.