问题
I have a common resource, which I want 1 and only 1 instance of my application (or it's COM API) to have access to at any time. I have tried to protect this resource using mutexes, but when multiple threads of a host dotnet application try to access the COM object, the mutex doesn't seem to be released. This is the code I have used to protect my resource.
repeat
Mutex := CreateMutex(nil, True, PChar('Connections'));
until (Mutex <> 0) and (GetLastError <> ERROR_ALREADY_EXISTS);
try
//use resource here!
finally
CloseHandle(Mutex);
end;
If I run the threads simultaneously, the first thread get's through (obviously, being the first one to create the mutex), but subsequent threads are caught in the repeat loop. If I run each thread at 5 second intervals, then all is ok.
I suspect I'm not using mutexes correctly here, but I have found very little documentation about how to do this.
Any ideas?
回答1:
You're using the mutex wrong. You should be waiting for it and releasing it, not recreating it constantly.
During initialization:
Mutex := CreateMutex(nil, False, 'Connections');
if Mutex = 0 then
RaiseLastOSError;
When you want to access the resource
if WaitForSingleObject(Mutex, INFINITE) <> WAIT_OBJECT_0 then
RaiseLastOSError;
try
// Use resource here
finally
ReleaseMutex(Mutex)
end;
During finalization
CloseHandle(Mutex);
Also, since mutexes are global, you should pick something a little more unique than "connections" for the name. We added a GUID to the end of ours.
回答2:
Try with this simple demo code. Start several instances of the application, and you can see from the background colour how they share the mutex:
procedure TForm1.FormCreate(Sender: TObject);
begin
fMutex := SyncObjs.TMutex.Create(nil, False, 'GlobalUniqueName');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
fMutex.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Color := clRed;
Update;
fMutex.Acquire;
try
Color := clGreen;
Update;
Sleep(5 * 1000);
finally
fMutex.Release;
end;
Color := clBtnFace;
end;
Note that I chose to use the TMutex
class from the SyncObjs
unit, which simplifies things.
来源:https://stackoverflow.com/questions/2470921/how-do-you-protect-a-common-resource-using-mutexes