Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
U kunt een mutex-object gebruiken om een gedeelde resource te beschermen tegen gelijktijdige toegang door meerdere threads of processen. Elke thread moet wachten op het eigendom van de mutex voordat deze de code kan uitvoeren die toegang heeft tot de gedeelde resource. Als bijvoorbeeld meerdere threads toegang tot een database delen, kunnen de threads een mutex-object gebruiken om slechts één thread tegelijk naar de database te schrijven.
In het volgende voorbeeld wordt de functie CreateMutex gebruikt om een mutex-object te maken en de functie CreateThread om worker threads te creëren.
Wanneer een thread van dit proces naar de database schrijft, wordt eerst het eigendom van de mutex aangevraagd met behulp van de functie WaitForSingleObject. Als de thread eigendom van de mutex verkrijgt, schrijft hij naar de database en geeft vervolgens zijn eigendom van de mutex vrij met behulp van de ReleaseMutex functie.
In dit voorbeeld wordt gestructureerde uitzonderingsafhandeling gebruikt om ervoor te zorgen dat de thread het mutex-object correct vrijgeeft. Het __finally codeblok wordt uitgevoerd, ongeacht hoe het __try blok wordt beëindigd (tenzij het __try blok een aanroep naar de functie TerminateThread bevat). Dit voorkomt dat het mutex-object per ongeluk wordt verlaten.
Als een mutex wordt verlaten, heeft de thread die eigenaar is van de mutex deze niet goed losgelaten voordat deze wordt beëindigd. In dit geval is de status van de gedeelde resource onbepaald en kan het gebruik van de mutex ertoe leiden dat een potentieel ernstige fout verhuld wordt. Sommige toepassingen proberen de resource mogelijk te herstellen naar een consistente status; dit voorbeeld retourneert gewoon een fout en stopt met het gebruik van de mutex. Zie Mutex-objectenvoor meer informatie.
#include <windows.h>
#include <stdio.h>
#define THREADCOUNT 2
HANDLE ghMutex; 
DWORD WINAPI WriteToDatabase( LPVOID );
int main( void )
{
    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 1;
    }
    // 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 1;
        }
    }
    // 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);
    return 0;
}
DWORD WINAPI WriteToDatabase( LPVOID lpParam )
{ 
    // lpParam not used in this example
    UNREFERENCED_PARAMETER(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; 
}