Studying example from MSDN article Using Mutex Objects some questions arise about mutex entity.
Here are experimentally proved suggestions:
Some create mutex via CreateMutex while having ERROR_ALREADY_EXISTS
Pic 1. Running 10 of these programs:
Example sources are here...
Run them with .bat script:
Here are experimentally proved suggestions:
- Mutexes are like files, open and create them with CreateMutex, close with CloseHandle (for files you use CreateFile, CloseHandle)
- Unnamed mutex is like critical section
- Mutexes are deleted after CloseHandle when no application currently have them opened
HANDLE hSome programs create h = 0x3c, some h = 0x44
main(){
h = CreateMutex("Global\\SuperMutex")
CreateThread(WriteToDatabase)
CloseHandle(h)
}
WriteToDatabase()
{
WaitForSingleObject(h)
ReleaseMutex(h)
}
Some create mutex via CreateMutex while having ERROR_ALREADY_EXISTS
Pic 1. Running 10 of these programs:
Example sources are here...
Run them with .bat script:
@echo off
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
start UsingMutex.exe
UsingMutex.cpp itself:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define THREADCOUNT 2
#define WRITE_ATTEMPTS 5
#define MUTEXNAME "Global\\SuperMutex"
HANDLE ghMutex;
DWORD WINAPI WriteToDatabase( LPVOID );
void main()
{
HANDLE aThread[THREADCOUNT];
DWORD thid;
int i;
ghMutex = CreateMutex(NULL, FALSE, MUTEXNAME);
//ghMutex = OpenMutex(NULL, FALSE, MUTEXNAME);
if (ghMutex==NULL) {
DWORD dw = GetLastError();
if (dw == ERROR_FILE_NOT_FOUND)
printf("CreateMutex error ERROR_FILE_NOT_FOUND\n");
else if (dw == ERROR_ACCESS_DENIED)
printf("CreateMutex error ERROR_ACCESS_DENIED\n");
else if (dw == ERROR_INVALID_HANDLE)
printf("CreateMutex error ERROR_INVALID_HANDLE\n");
else
printf("CreateMutex error %d\n", dw);
return;
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
printf("CreateMutex error ERROR_ALREADY_EXISTS\n");
}
printf("Created Mutex 0x%x\n", ghMutex);
for(i=0; i<THREADCOUNT; i++)
{
aThread[i]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteToDatabase, NULL, 0, &thid);
if(aThread[i] == NULL) {
printf("CreateThread error: %d\n", GetLastError());
return;
}
}
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
for(i=0; i<THREADCOUNT; i++)
CloseHandle(aThread[i]);
CloseHandle(ghMutex);
printf("Press Any Key to continue...\n");
getch();
}
DWORD WINAPI WriteToDatabase( LPVOID )
{
DWORD dwCount=0, dwWaitResult;
while(dwCount<WRITE_ATTEMPTS)
{
dwWaitResult = WaitForSingleObject(ghMutex, INFINITE);
switch(dwWaitResult)
{
case WAIT_OBJECT_0:
__try {
printf("Thread % d writing to database...\n", GetCurrentThreadId());
dwCount++;
}
__finally{
printf("Thread % d finished\n", GetCurrentThreadId());
if (!ReleaseMutex(ghMutex))
{
//TODO
}
}
break;
case WAIT_ABANDONED:
return FALSE;
}
}
return TRUE;
}
No comments:
Post a Comment