2012-03-30 8 views
0

Ich schaffe ein Programm, das die gleiche Funktion in mehrere Prozesse und mehrere Threads ausgeführt werden soll, damit ich eine Funktion erstellt erreichen Verriegeln und Synchronisation, dieLocking und Synchronisation unter Verwendung Mutex

HANDLE WaitOnMutex(char* mt) 
{ 
    HANDLE ghMutex=NULL; 
    DWORD lastError=-1; 
    do 
    { 
     ghMutex = CreateMutex(NULL,TRUE,mt); 
     lastError= GetLastError(); 
     if(lastError!=ERROR_SUCCESS) 
     { 
      CloseHandle(ghMutex); 
      Sleep(2000); 
     } 
    } 
    while(lastError!=ERROR_SUCCESS); 
    return ghMutex; 
} 

ist, und ich bin mit es wie die folgenden

HANDLE mtx=WaitOnMutex("Global\\DBG_MY_APP"); 
    //Do the work that needs sync 
    CloseHandle(mtx) 

Ist dies eine ordnungsgemäße Möglichkeit, diese Funktion zu sperren? oder brauche ich eine andere Methode verwenden ..

Hinweis: Ich bin mit „Global“, weil einige Teile meiner App WINSERVICE ist und ich brauche zwischen sitzungs Isolierte Prozesse

Der Code sperren arbeitet in Testumgebung, aber ich bin mir nicht sicher, ob ich es richtig mache

+0

Sie verwenden den falschen Weg. Weitere Informationen finden Sie in dieser Dokumentation. [Mutex msdn] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927%28v=vs.85%29.aspx) – rbelli

+0

@rbelli kann plz mir sagen, was genau falsch mit meinem Weg ? – CnativeFreak

+1

Wenn ich genau verstehe, was Sie tun, erstellen oder öffnen Sie nur den Mutex. Du bekommst den Mutex nicht. Dazu müssen Sie, wie ich im Beispiel sehen kann, die Funktion WaitForSingleObjects für check aufrufen und den Mutex holen und dann die Funktion ReleaseMutex aufrufen, um sie freizugeben. – rbelli

Antwort

4

Was Sie haben, ist eine hektische Wartezeit, die unter den meisten Umständen weniger als ideal ist. Nicht nur das, aber Sie haben es in Schwergewicht Mutex Creation und Release-Anrufe eingewickelt.

Um einen benannten Mutex für die prozessübergreifende Synchronisierung zu verwenden, sollte jeder Prozess CreateMutex nur einmal aufrufen. Sie halten dann den Mutex-Griff herum und verwenden WaitForSingleObject, um darauf zu warten, und ReleaseMutex, um die Sperre aufzuheben. Sie können es dann erneut mit WaitForSingleObject beim nächsten Mal sperren, wenn Sie auf die geschützte Ressource zugreifen müssen, und so weiter.

Wenn Ihr Prozess mit dem Mutex "für immer" beendet ist (z. B. weil der Prozess beendet wird), rufen Sie CloseHandle.

+0

Schön, aber erstens glaube ich nicht, dass es beschäftigt ist warten bcoz von "Sleep (2000);" aber ich denke, du hast Recht mit Schwergewicht Mutex-Erstellung. Jetzt ist meine Frage Funktion CreateMutex unterbrechbar? Wenn ja, dann ist meine ganze Arbeit falsch, wenn nicht meine Arbeit in der Leistung schlecht ist. – CnativeFreak

+1

Zugegeben, eine Wartezeit von 2 Sekunden ist nicht "beschäftigt", aber es ist noch eine Abfrageschleife, die den Scheduler benötigt, um den Faden nur aufzuwachen Überprüfen Sie, ob es den Mutex erhalten kann und gehen Sie dann wieder in den Schlafmodus. –

+1

'CreateMutex' kann aufgrund von Planungsproblemen nicht fehlschlagen, es sei denn, der andere Thread/Prozess, der den Mutex erstellt, ändert die Zugriffsrechte, sodass Ihr Thread/Prozess nicht über die erforderlichen Berechtigungen verfügt. Wenn das nicht geschieht, erstellt entweder Ihr Thread den Mutex, und Sie erhalten die Sperre (weil Sie das Flag "initial owner" als "true" angegeben haben) oder der andere Thread den Mutex erstellt und Sie den Handle und ein ERROR_ALREADY_EXISTS erhalten Fehlercode, aber nicht die Sperre. –

2

Ich denke, das wird funktionieren, für eine ausreichend lose Definition von "Arbeit". Es ist nicht so, wie ich den Job machen würde.

Ich glaube, ich Dinge wie diese mehr tun würde:

Irgendwo in einmaliger Initialisierungscode:

HANDLE mutex = CreateMutex(name); // yes, there are more parameters here. 

dann in das Protokoll zu schreiben:

WaitForSingleObject(mutex, INFINITE); 

// write to log 

ReleaseMutex(handle); 

dann während Einmaliger Abschaltcode:

CloseHandle(mutex); 

Wenn Sie C++ anstelle von C verwenden, möchten Sie dies normalerweise über RAII behandeln, also würden Sie ein Protokollobjekt erstellen, das den Aufruf CreateMutex in seinem ctor ausführt, und den CloseHandle Aufruf in es dtor. Dann würden Sie einen Schreibfunktor haben, der die WaitForSingleObject in seinem ctor tut, schreibt zum Log in seinem operator(), und tut das ReleaseMutex in seinem dtor. Dies hält den Großteil Ihres Codes relativ einfach und gewährleistet die Ausnahmesicherheit mit wenig oder gar keiner zusätzlichen Arbeit.

+0

Hoppla - sieht so aus, als hätte Anthony mich dazu geschlagen. –

+0

Meine neue Frage: ist die Funktion CreateMutex unterbrechbar? Wenn ja, dann ist meine ganze Arbeit falsch, wenn nicht, dann ist meine Arbeit schlecht in der Leistung. – CnativeFreak

+0

Ich nehme an, es hängt ein bisschen davon ab, was du mit unterbrechbar meinst, aber zu deinem Code verhält es sich wie atomar. –