CreateMutexA 函式 (synchapi.h)

建立或開啟具名或未命名的 mutex 物件。

若要指定物件的存取遮罩,請使用 CreateMutexEx 函式。

語法

HANDLE CreateMutexA(
  [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
  [in]           BOOL                  bInitialOwner,
  [in, optional] LPCSTR                lpName
);

參數

[in, optional] lpMutexAttributes

SECURITY_ATTRIBUTES 結構的指標。 如果此參數為 NULL,子進程就無法繼承句柄。

結構的 lpSecurityDescriptor 成員會指定新 Mutex 的安全性描述元。 如果 lpMutexAttributesNULL,mutex 會取得預設的安全性描述元。 Mutex 預設安全性描述元中的 ACL 來自建立者的主要或模擬令牌。 如需詳細資訊,請參閱 同步處理物件安全性和訪問許可權

[in] bInitialOwner

如果此值為 TRUE ,且呼叫端建立了 mutex,則呼叫線程會取得 mutex 物件的初始擁有權。 否則,呼叫線程不會取得 mutex 的擁有權。 若要判斷呼叫端是否建立 mutex,請參閱傳回值一節。

[in, optional] lpName

mutex 物件的名稱。 名稱限制為 MAX_PATH 個字元。 名稱比較區分大小寫。

如果 lpName 符合現有具名 mutex 物件的名稱,此函式會要求 MUTEX_ALL_ACCESS 訪問許可權。 在此情況下, 系統會忽略 bInitialOwner 參數,因為它已經由建立程式設定。 如果 lpMutexAttributes 參數不是 NULL,它會判斷是否可以繼承句柄,但會忽略其安全性描述元成員。

如果 lpNameNULL,則會建立 mutex 物件,而不需名稱。

如果 lpName 符合現有事件、旗號、可等候的定時器、作業或檔案對應對象的名稱,則函式會失敗, 而且 GetLastError 函式會傳回 ERROR_INVALID_HANDLE。 這是因為這些對象共用相同的命名空間。

名稱可以有 「Global」 或 「Local」 前置詞,以在全域或會話命名空間中明確建立物件。 名稱的其餘部分可以包含任何字元,但反斜杠字元 (\) 除外。 如需詳細資訊,請參閱 核心物件命名空間。 使用終端機服務會話實作快速使用者切換。 核心物件名稱必須遵循終端機服務概述的指導方針,讓應用程式可以支援多個使用者。

物件可以在私人命名空間中建立。 如需詳細資訊,請參閱 物件命名空間

傳回值

如果函式成功,則傳回值是新建立 Mutex 物件的句柄。

如果函式失敗,則傳回值為 NULL。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

如果 mutex 是具名 mutex,且物件存在於此函式呼叫之前,傳回值就是現有物件的句柄, 而 GetLastError 函式會傳回 ERROR_ALREADY_EXISTS

備註

CreateMutex 傳回的句柄具有MUTEX_ALL_ACCESS訪問許可權;它可用於任何需要 mutex 物件的句柄的函式中,前提是呼叫端已獲得存取權。 如果 mutex 是從服務或模擬不同使用者的線程建立,您可以在建立 Mutex 時將安全性描述元套用至 mutex,或變更建立程式的預設安全性描述元,方法是變更其預設 DACL。 如需詳細資訊,請參閱 同步處理物件安全性和訪問許可權

如果您使用具名 Mutex 將應用程式限制為單一實例,惡意使用者可以先建立此 Mutex,再執行並防止應用程式啟動。 若要避免這種情況,請建立隨機命名的 mutex 並儲存名稱,使其只能由授權使用者取得。 或者,您也可以針對此目的使用檔案。 若要將您的應用程式限制為每個使用者一個實例,請在使用者的配置檔目錄中建立鎖定的檔案。

呼叫進程的任何線程都可以在呼叫其中一個 等候函式中指定 mutex-object 句柄。 當指定物件的狀態發出訊號時,單一物件等候函式會傳回。 當任一物件或發出所有指定物件的訊號時,可以指示多物件等候函式傳回。 當等候函式傳回時,等候線程會釋放以繼續執行。

當 mutex 物件不是由任何線程擁有時,就會發出訊號。 建立線程可以使用 bInitialOwner 旗標來要求 mutex 的立即擁有權。 否則,線程必須使用其中一個等候函式來要求擁有權。 當 Mutex 的狀態發出訊號時,會授與一個等候線程擁有權、mutex 的狀態變更為非簽署,而等候函式會傳回。 在任何指定的時間,只有一個線程可以擁有 Mutex。 擁有線程會使用 ReleaseMutex 函式來釋放其擁有權。

擁有 mutex 的線程可以在重複的等候函式呼叫中指定相同的 mutex,而不會封鎖其執行。 一般而言,您不會重複等候相同的 Mutex,但此機制會防止線程在等候已經擁有的 Mutex 時自行死結。 不過,若要釋放其擁有權,線程必須在每次 Mutex 滿足等候時呼叫 ReleaseMutex 一次。

兩個或多個進程可以呼叫 CreateMutex 來建立相同的具名 mutex。 第一個程序實際上會建立 mutex,而後續進程具有足夠的訪問許可權,只要開啟現有 Mutex 的句柄即可。 這可讓多個進程取得相同 Mutex 的句柄,同時減輕使用者負責確保先啟動建立程式的責任。 使用這項技術時,您應該將 bInitialOwner 旗標設定為 FALSE;否則,可能很難確定哪個程式具有初始擁有權。

多個進程可以有相同 Mutex 物件的句柄,讓對象能夠用於進程間同步處理。 下列物件共享機制可供使用:

  • 如果 CreateMutexAttributes 參數已啟用 CreateMutex 繼承的 lpMutexAttributes 參數,CreateProcess 函式所建立的子進程可以繼承 mutex 物件的句柄。 此機制適用於具名和未命名的 Mutex。
  • 進程可以在呼叫 DuplicateHandle 函式時指定 mutex 物件的句柄,以建立可由另一個進程使用的重複句柄。 此機制適用於具名和未命名的 Mutex。
  • 進程可以在呼叫 [OpenMutex] (./nf-synchapi-openmutexw.md) 或 CreateMutex 來擷取 mutex 物件的句柄中指定具名 mutex。
使用 CloseHandle 函式 關閉句柄。 系統會在進程終止時自動關閉句柄。 當最後一個句柄關閉時,Mutex 物件就會終結。

範例

如需 CreateMutex 的範例,請參閱使用 Mutex 物件

注意

synchapi.h 標頭會將 CreateMutex 定義為別名,根據 UNICODE 預處理器常數的定義,自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱 函式原型的慣例

規格需求

需求
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 synchapi.h (Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2)
程式庫 Kernel32.lib
DLL Kernel32.dll

另請參閱

CloseHandle

CreateMutexEx

CreateProcess

DuplicateHandle

Mutex 物件

物件名稱

OpenMutex

ReleaseMutex

SECURITY_ATTRIBUTES

同步處理函式