Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Você pode usar um objeto mutex para proteger um recurso compartilhado contra acesso simultâneo por vários threads ou processos. Cada thread deve aguardar a propriedade do mutex antes que ele possa executar o código que acessa o recurso compartilhado. Por exemplo, se vários threads compartilharem acesso a um banco de dados, os threads poderão usar um objeto mutex para permitir que apenas um thread por vez escreva no banco de dados.
O exemplo a seguir usa a função CreateMutex para criar um objeto mutex e a função CreateThread para criar threads de trabalho.
Quando um thread desse processo é gravado no banco de dados, ele primeiro solicita a propriedade do mutex usando a função WaitForSingleObject . Se o thread obtiver a propriedade do mutex, ele gravará no banco de dados e liberará sua propriedade do mutex usando a função ReleaseMutex .
Este exemplo usa o tratamento de exceção estruturado para garantir que o thread libere corretamente o objeto mutex. O bloco de código __finally é executado independentemente de como o bloco __try é encerrado (a menos que o bloco __try inclua uma chamada para a função TerminateThread ). Isso impede que o objeto mutex seja abandonado inadvertidamente.
Se um mutex for abandonado, o thread que possuía o mutex não o liberou corretamente antes de terminar. Nesse caso, o status do recurso compartilhado é indeterminado e continuar a usar o mutex pode obscurecer um erro potencialmente grave. Alguns aplicativos podem tentar restaurar o recurso para um estado consistente; este exemplo simplesmente retorna um erro e para de usar o mutex. Para obter mais informações, consulte Objetos Mutex.
#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;
}