Aby określić maskę dostępu do obiektu, należy użyć funkcji CreateMutexEx. |
Składnia
#include <windows.h>
HANDLE WINAPI CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
Argumenty
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ę
GetLastError.
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):
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
Linki zewnętrzne