Unbehandelte Ausnahme-Zugriffsverletzung schriftlich Lage in einer Mutex-Beispiel
Arbeite ich durch ein Beispiel der Schutz einer globalen doppelten Verwendung von Mutexe, jedoch bekomme ich die Fehlermeldung -
Nicht behandelte Ausnahme bei 0x77b6308e in
Lab7.exe: 0xC0000005: Zugriffsverletzung
schreiben Lage 0x00000068.
Ich nehme an, dies ist im Zusammenhang mit dem Zugriff auf Punktzahl? (Die Globale double)
#include <windows.h>
#include <iostream>
#include <process.h>
double score = 0.0;
HANDLE threads[10];
CRITICAL_SECTION score_mutex;
unsigned int __stdcall MyThread(void *data)
{
EnterCriticalSection(&score_mutex);
score = score + 1.0;
LeaveCriticalSection(&score_mutex);
return 0;
}
int main()
{
InitializeCriticalSection(&score_mutex);
for (int loop = 0; loop < 10; loop++)
{
threads[loop] = (HANDLE) _beginthreadex(NULL, 0, MyThread, NULL, 0, NULL);
}
WaitForMultipleObjects(10, threads, 0, INFINITE);
DeleteCriticalSection(&score_mutex);
std::cout << score;
while(true);
}
Update:
Nach dem beheben des Problems mit der Schleife gesetzt, um 1000 statt 10, der Fehler immer noch aufgetreten ist, aber wenn ich auskommentiert den code-Stücken, die unter Bezugnahme auf den mutex der Fehler nicht auftreten.
CRITICAL_SECTION score_mutex;
EnterCriticalSection(&score_mutex);
LeaveCriticalSection(&score_mutex);
InitializeCriticalSection(&score_mutex);
DeleteCriticalSection(&score_mutex);
Update 2
Threads return 0 gemäß Konvention (Es war eine lange Woche!)
Habe ich versucht, indem Sie zurück in die mutex-code, und das Programm wird kompiliert und laufen problemlos (anders als die race-condition-Probleme mit dem double natürlich) mit CRITICAL_SECTION, InitializeCriticalSection und DeleteCriticalSection alle wieder in Hinzugefügt. Das problem scheint zu sein, mit EnterCriticalSection oder LeaveCriticalSection, als der Fehler erneut Auftritt, wenn ich diese hinzufügen.
Haben Sie überprüft den Rückgabewert von jeder der aufgerufen Funktionen? überprüfen Sie Immer die error-codes vom C-API-Funktionen. Es ist der erste Schritt sollten Sie, vor allem wenn man einen crash!
Danke - ich sollte gedacht haben - es war eine lange Woche!
Finden Sie Ihre Fehler, überprüfen Sie heraus meine Antwort.
Sie brauchen nicht eine busy-loop
while(true);
am Ende. WaitForMultipleObjects
wartet, bis alle sekundären threads so, dass der primäre thread nicht beenden.InformationsquelleAutor Eilidh | 2011-05-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den verbleibenden Fehler in deinem code ist der Aufruf
WaitForMultipleObjects()
. Legen Sie den 3. parameter0
(FALSE
), so dass der Haupt-thread verstopfte sobald alle von den 10 threads beendet.Dies bewirkt, dass der Aufruf
DeleteCriticalSection()
ausführen, bevor alle threads fertig sind, erstellen eine Zugriffsverletzung, wenn eine der (möglicherweise) 9 andere threads startet und fordertEnterCriticalSection()
.TRUE
um den Fehler zu beheben.Oh verflucht, ich hatte mir eigentlich, dass die Herstellung von einem anderen Fehler, und legen Sie den Wert TRUE (in einem anderen Beispiel) und dann prompt vergessen! Vielen Dank 🙂
Mit dieser Antwort, es ist gut zu wissen, dass der Aufruf von DeleteCriticalSection() verursacht eine Zugriffsverletzung in einem anderen thread auf EnterCriticalSection(). Es ist natürlich leicht zu verstehen, aber wenn eine Zugriffsverletzung erscheint die erste, vielleicht auch nicht.
InformationsquelleAutor André Caron
Schreiben Sie über das Ende Ihrer
threads[10]
array:threads
nur in Größe 10!Ich glaube, Sie brauchen zu initialisieren, Ihre kritischen Abschnitt-Objekt:
score_mutex
mitInitializeCriticalSection
auch.Es ist nur am Anfang von main? Ist es falsch?
Oh, verpasst. Nein sieht alles okay jetzt. Wenn man im debugger die Zeile der Fehler tritt auf?
InformationsquelleAutor James
Dein problem ist, dass WaitForMultipleObjects wartet nicht auf alle threads abgeschlossen ist, wodurch der kritische Abschnitt werden vorzeitig gelöscht. Nach MSDN, das Dritte argument ist
Du dies auf 0 gesetzt, die zurückgegeben wird, wenn Ihr threads schließt. Dies führt zu folgenden DeleteCriticalSection ausgeführt werden, solange es noch threads warten darauf zugreifen.
InformationsquelleAutor Doug T.
Sollten Sie auch erklären, score als flüchtige, so dass Sie nicht haben zwischengespeicherten Wert problem.
InformationsquelleAutor Hyksos