Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Você pode usar um objeto mutex para proteger um recurso compartilhado do acesso simultâneo por vários threads ou processos. Cada thread deve aguardar a propriedade do mutex antes de poder executar o código que acessa o recurso compartilhado. Por exemplo, se vários threads compartilharem o acesso a um banco de dados, os threads poderão usar um objeto mutex para permitir que apenas um thread de cada vez grave 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 uma thread deste processo escreve no banco de dados, ela primeiro solicita a propriedade do mutex usando a função WaitForSingleObject. Se o thread obtém a propriedade do mutex, ele grava no banco de dados e, em seguida, libera sua propriedade do mutex usando a funçãoReleaseMutex.
Este exemplo usa o tratamento de exceções estruturadas para garantir que o thread libere corretamente o objeto mutex. O bloco de código __finally é executado independentemente de como o bloco __try termina (a menos que o bloco __try inclua uma chamada para a funçãoTerminateThread). Isso evita que o objeto mutex seja abandonado inadvertidamente.
Se um mutex for abandonado, o fio 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 Mutex Objects.
#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;
}