Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Hasło nie zostało zweryfikowane
Niniejsze hasło zostało opracowane, jednak nie zostało ono zweryfikowane przez administrację serwisu. Jeżeli znalazłeś błędy merytoryczne w niniejszym dokumencie, prosimy o ich zgłoszenie na forum w dziale Znalezione błędy.
Opracował: jankowalski25
Biblioteki C/C++

CreateMutex

[funkcja] Tworzy lub otwiera muteks.
Aby określić maskę dostępu do obiektu, należy użyć funkcji CreateMutexEx.

Składnia

C/C++
#include <windows.h>
HANDLE WINAPI CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);

Argumenty

ArgumentOpis
lpMutexAttributesWskaźnik do struktury SECURITY_ATTRIBUTES. Jeśli wartość tego argumentu wynosi NULL, uchwyt nie może być dziedziczony przez procesy potomne. Pole lpSecurityDescriptor tej struktury określa deskryptor zabezpieczeń dla nowego muteksu. Jeśli wartość tego argumentu wynosi NULL, muteks używa domyślnego deskryptora zabezpieczeń. Wartość ACL w domyślnym deskryptorze zabezpieczeń dla muteksu pochodzi z podstawowego tokenu impersonacji kreatora.
bInitialOwnerJeśli wartośc tego argumentu wynosi TRUE i wywołujący utworzył muteks, bieżący wątek staje się właścicielem obiektu muteksu, inaczej bieżący wątek nie jest właścicielem muteksu.
lpNameNazwa obiektu muteksu. Nazywanie muteksów jest opcjonalne. Długość tej nazwy nie może przekroczyć MAX_PATH znaków. Przy porównywaniu nazw jest uwzględniana wielkość liter. Jeśli wartość tego argumentu jest nazwą istniejącego obiektu muteksu, ta funkcja wymaga uprawnień dostępu MUTEX_ALL_ACCESS. W tym przypadku wartość argumentu bInitialOwner jest ignorowana, ponieważ została już ustawiona przez wywoływany proces. Jeśli wartość argumentu lpMutexAttributes nie jest równa NULL, to określa, czy uchwyt może być dziedziczony, ale składowa deskryptora zabezpieczeń jest ignorowana, inaczej obiekt muteksu jest tworzony bez nazwy. Jeśli wartość argumentu lpName jest nazwą istniejącego zdarzenia, semafora, timera, zadania lub obiektu mapowania pliku, funkcja kończy się niepowodzeniem i kolejne wywołanie funkcji » WinAPIGetLastError zwraca wartość ERROR_INVALID_HANDLE. Przyczyną tego błędu jest umieszczenie tych obiektów w tej samej przestrzeni nazw. Aby temu zapobiec, należy dodać do nazwy przedrostek Global\ lub Local\, co pozwala na jawne otworzenie obiektu w globalnej lub lokalnej przestrzeni nazw. Dalsza część takiej nazwy może zawierać dowolne znaki, oprócz znaków backslash (\). Jeśli nazwa muteksu jest już zajęta i obiekt muteksu istniał przed wywołaniem tej funkcji, zwracaną wartością jest uchwyt do istniejącego muteksu, natomiast funkcja » WinAPIGetLastError zwraca wartość ERROR_ALREADY_EXISTS, wartość argumentu bInitialOwner jest ignorowana oraz wywoływany wątek nie jest właścicielem muteksu. Jednak jeśli wywołujący ograniczył dostęp do muteksu, funkcja kończy się niepowodzeniem, a funkcja » WinAPIGetLastError zwraca wartość ERROR_ACCESS_DENIED, natomiast wywołujący powinien użyć funkcji OpenMutex.

Zwracana wartość

Zwracana wartość pozwala określić, czy wywołujący utworzył muteks. Jeśli funkcja zakończy się bez błędów, funkcja zwraca uchwyt do nowego obiektu muteksu. Jeśli funkcja zakończy się niepowodzeniem, funkcja zwraca wartość NULL. Aby uzyskać rozszerzone informacje o błędach, należy wywołać funkcję » WinAPIGetLastError.

Dodatkowe informacje

Szybkie przełączanie użytkowników używa sesji usług terminala. Nazwy obiektów kernela muszą być zgodne z wytycznymi podanymi dla usług terminala. Dzięki temu jest możliwa obsługa wielu użytkowników. Obiekt może również zostać utworzony w prywatnej przestrzeni nazw. Uchwyt zwracany przez tą funkcję ma zawsze dostęp MUTEX_ALL_ACCESS i może być używany w dowolnej funkcji wymgającej uchwytu do obiektu muteksu. Taka funkcja musi zapewniać, że wywołujący będzie miał pełny dostęp do muteksu. Jeśli muteks jest tworzony z usługi lub wątku impersonowanego przez innego użytkownika, można również użyć deskryptora zabezpieczeń do zabezpieczenia tworzonego muteksu lub zmienić domyślny deskryptor zabezpieczeń dla tworzonego procesu przez zmianę domyślnej wartości DACL. Funkcja CreateMutex zakończy się powodzeniem nawet jeśli muteks istnieje, ale w tym przypadku zwróci ERROR_ALREADY_EXISTS. W tej sytuacji inna instancja tego programu musi być już uruchomiona, ponieważ pierwsza utworzyła muteks. Jednak złośliwy użytkownik może utworzyć ten muteks przed uruchomieniem programu i zapobiec jego uruchomieniu. Aby temu zapobiec sytuacji, należy utworzyć muteks o losowej nazwie i przechowywać go tak, aby tylko wybrany użytkownik mógł ją pobrać. W tym celu można użyć specjalnie zabezpieczonego pliku w folderze profilu użytkownika. Każdy wątek wywoływanego procesu może pobrać uchwyt do obiektu muteksu poprzez wywołanie jednej z funkcji oczekujących. Pojedyncza funkcja oczekująca kończy działanie, gdy obiekt znajdzie się w wymaganym stanie. Funkcje oczekujące na wiele obiektów mogą kończyć swoje działanie, gdy jeden lub wszystkie określone obiekty znajdą się w odpowiednim stanie. Gdy takie funkcje zakończą swoje działanie, oczekujący wątek może kontynuować swoją pracę. Stan obiektu muteksu jest uznawany za odpowiedni, gdy ten obiekt nie należy do żadnego wątku. Tworzony wątek może wykorzystywać wartość argumentu bInitialOwner do żądania przydzielenia własności do muteksu. Inaczej wątek musi użyć jednej z funkcji oczekujących, aby zrealizować żądanie. Kiedy stan muteksu jest odpowiedni, jeden z oczekujących wątków staje się właścicielem, stan muteksu ulega zmianie i funkcje oczekujące kończą swoje działanie. Tylko jeden wątek może być właścicielem muteksu w danym momencie. Mechanizm własności wątków używa funkcji ReleaseMutex do jej zwalniania. Wątek będący właścicielem muteksu może pobrać ten sam muteks w funkcji powtarzającej swoje wywołania bez blokowania wykonywania wątku. W typowej sytuacji programista nie chce wywoływać cały czas takiej funkcji dla tego samego muteksu. Dlatego ten mechanizm zapobiega takiej sytuacji (nazywanej zakleszczeniem) podczas oczekiwania na muteks, który jest obecnie właścicielem. Mimo tego wątek, który ma przestać być właściclelem musi wywołać funkcję ReleaseMutex za każdym razem, gdy muteks oczekuje na zwolnienie. Dwa lub więcej procesów może wywołać tą funkcję w celu utworzenia muteksów o tej samej nazwie. W tej sytuacji pierwszy proces tworzy muteks, natomiast następne procesy mające odpowiedni dostęp mogą otworzyć uchwyt do istniejącego muteksu. To pozwala na współdzielenie danego muteksu przez wiele procesów i zwalnia użytkownika od odpowiedzialności za kolejność tworzenia procesów. Podczas używania tej techniki, wartość argumentu bInitialOwner powinna wynosić FALSE, ponieważ inaczej może wystąpić problem z ustaleniem, który proces będzie pierwszym właścicielem. Wiele procesów może mieć uchwyty do tego samego obiektu muteksu, co pozwala na używanie takiego obiektu do ich synchronizacji. Ten mechanizm można wykorzystać używając jednego z poniższych sposobów (dwie pierwsze metody działają zarówno dla nazwanych, jak również nienazwanych muteksów):
  • Proces potomny utworzony przez wywołanie funkcji CreateProcess może dziedziczyć uchwyt do obiektu muteksu, jeśli wartość argumentu lpMutexAttributes pozwala na dziedziczenie.
  • Proces może określić uchwyt do obiektu muteksu przez wywołanie funkcji DuplicateHandle w celu utworzenia drugiego uchwytu, który może zostać wykorzystany przez inny proces.
  • Proces może określić nazwany muteks przez wywołanie funkcji OpenMutex lub tej funkcji w celu pobrania uchwytu do obiektu muteksu
Funkcja CloseHandle pozwala na zamknięcie takiego uchwytu. System zamyka uchwyty automatycznie podczas zamykania procesu. Obiekt muteksu jest niszczony, gdy ostatni uchwyt zostanie zamknięty.

Wymagania

Minimalny system klientaWindows XP (tylko aplikacje biurowe).
Minimalny system serweraWindows Server 2003 (tylko aplikacje biurowe).
NagłówekWinBase.h (dołącza Windows.h) lub Synchapi.h (dla systemu Windows 8 lub Windows Server 2012).
BibliotekaKernel32.lib
DLLKernel32.dll
UNICODECreateMutexW
ANSICreateMutexA

Linki zewnętrzne