互斥體

ate ate creatin

互斥體簡介

互斥體實現了“互相排斥”(mutual exclusion)同步的簡單形式(所以名為互斥體(mutex))。互斥體禁止多個執行緒同時進入受保護的代碼“臨界區”(critical section)。因此,在任意時刻,只有一個執行緒被允許進入這樣的代碼保護區。任何執行緒在進入臨界區之前,必須獲取(acquire)與此區域相關聯的互斥體的所有權。如果已有另一執行緒擁有了臨界區的互斥體,其他執行緒就不能再進入其中。這些執行緒必須等待,直到當前的屬主執行緒釋放(release)該互斥體。什麼時候需要使用互斥體呢?互斥體用於保護共享的易變代碼,也就是,全局或靜態數據。這樣的數據必須通過互斥體進行保護,以防止它們在多個執行緒同時訪問時損壞。

互斥體的創建

在VC中,我們用CreateMutex函式創建互斥體。
HANDLE WINAPI CreateMutex(
__in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
__in BOOL bInitialOwner,
__in_opt LPCTSTR lpName
);

套用示例

#include <windows.h>
#include <stdio.h>
#define THREADCOUNT 2
HANDLE ghMutex;
DWORD WINAPI WriteToDatabase( LPVOID );
void main()
{
HANDLE aThread&#91;THREADCOUNT&#93;;
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&#91;i&#93; = 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&#91;i&#93; == 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&#91;i&#93;);
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;
}

微軟MSDN中關於互斥體的備註

The handle returned by CreateMutex has MUTEX_ALL_ACCESS access to the new mutex object and can be used in any function that requires a handle to a mutex object.
通過CreateMutex 函式返回的句柄擁有MUTEX_ALL_ACCESS 許可權,並且可以在任何函式中請求這個互斥體對象句柄。
Any thread of the calling process can specify the mutex-object handle in a call to one of the wait functions.
任何調用進程的執行緒均可以在WAIT系列的函式中指定這個互斥體對象句柄。
The single-object wait functions return when the state of the specified object is signaled.
單個對象的等待函式(例如:SignalObjectAndWait, WaitForSingleObject, and WaitForSingleObjectEx )會在指定對象的狀態變為受信狀態後返回。
The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.
多對象的等待函式將等待任意一個或全部對象都變成受信狀態後返回(取決於函式的參數設定)。當等待函式返回,等待執行緒將繼續執行下去。
The state of a mutex object is signaled when it is not owned by any thread.
當互斥體對象不屬於任何一個執行緒時,互斥體的狀態為受信狀態。
The creating thread can use the bInitialOwner flag to request immediate ownership of the mutex.
創建執行緒可以使用bInitialOwner 標誌請求立即獲得該互斥體的擁有權。
Otherwise, a thread must use one of the wait functions to request ownership.
否則,執行緒必須使用一種等待函式請求擁有權。
When the mutex's state is signaled, one waiting thread is granted ownership, the mutex's state changes to nonsignaled, and the wait function returns. Only one thread can own a mutex at any given time. The owning thread uses the ReleaseMutex function to release its ownership.
當互斥體對象為受信狀態時,假定某個等待執行緒獲得了其擁有權,互斥體狀態轉為非受信(無信號)狀態時,等待函式返回。同一時間只能有一個執行緒可以擁有某一互斥體。該執行緒可以使用ReleaseMutex 函式釋放擁有權。
The thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution. Typically, you would not wait repeatedly for the same mutex, but this mechanism prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.
一個對某一互斥體擁有所有權的執行緒可以在重複等待函式中指定已經擁有的那個互斥體(為等待對象),這並不會阻塞執行緒的執行。典型的例子是,你可能不需要重複等待同一個互斥體(言下之意,你寫了重複的等待某一個互斥體對象的代碼),這種機制預防了執行緒在已經擁有了互斥體對象的所有權的時候還要繼續等待該互斥體對象時造成的死鎖問題。但是,釋放所有權時必須調用同樣多次數的ReleaseMutex 函式。
Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes open a handle to the existing mutex.
一個或多個進程可以調用CreateMutex 函式創建一個同名的互斥體,第一個進程真正意義上的創建該互斥體,之後的進程只是打開已經存在的互斥體的句柄。
This enables multiple processes to get handles of the same mutex, while relieving the user of the responsibility of ensuring that the creating process is started first. When using this technique, you should set the bInitialOwner flag to FALSE; otherwise, it can be difficult to be certain which process has initial ownership.
允許多進程獲得同一互斥體的句柄,可以幫助負責任的使用者(使用互斥體的開發人員)確保創建的進程是第一個被運行的進程。(防止遊戲多開的方法之一^_^)。使用這種技術你應該設定bInitialOwner 標誌為FALSE,否則將很難確定哪個進程有(互斥體的)最初所有權。
Multiple processes can have handles of the same mutex object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available: 多進程可以獲得同一互斥體對象的句柄,使得該對象可以用於進程間同步。 A child process created by the CreateProcess function can inherit a handle to a mutex object if the lpMutexAttributes parameter of CreateMutex enabled inheritance.
如果使用CreateMutex 函式時lpMutexAttributes 參數允許繼承,則使用CreateProcess 函式創建的子進程可以繼承互斥體對象的句柄。
A process can specify the mutex-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process. A process can specify the name of a mutex object in a call to the OpenMutex or CreateMutex function.
進程可以在DuplicateHandle 函式中指定互斥體對象句柄去創建一個複製句柄,以便用於其它進程。進程可以在OpenMutex 函式或CreateMutex 函式中指定互斥體對象的名稱。
Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.
使用CloseHandle 函式關閉句柄,系統會在進程銷毀時自動關閉句柄,互斥體對象在最後一個句柄被關閉時被銷毀。

相關詞條

相關搜尋

熱門詞條

聯絡我們