Ich denke, dieser Artikel basiert auf einem grundlegenden Missverständnis darüber, wozu CSingleLock dient und wie es zu verwenden ist.
Sie können ein und dasselbe CSingleLock nicht mehrfach sperren, aber das ist auch nicht vorgesehen. CSingleLock ist, wie der Name schon sagt, dazu da, etwas EINMAL zu sperren.
Jedes CSingleLock verwaltet nur eine Sperre für ein anderes Objekt (z. B. eine CCriticalSection, die Sie ihm während der Konstruktion übergeben), mit dem Ziel, diese Sperre automatisch freizugeben, wenn das CSingleLock den Anwendungsbereich verlässt.
Wenn Sie das zugrundeliegende Objekt mehrfach sperren wollen, würden Sie mehrere CSingleLocks verwenden; Sie würden nicht ein einziges CSingleLock verwenden und versuchen, es mehrfach zu sperren.
Falsch (sein Beispiel):
CCriticalSection crit;
CSingleLock lock(&crit);
lock.Lock();
lock.Lock();
lock.Unlock();
lock.Unlock();
Richtig:
CCriticalSection crit;
CSingleLock lock1(&crit);
CSingleLock lock2(&crit);
lock1.Lock();
lock2.Lock();
lock2.Unlock();
lock1.Unlock();
Noch besser (damit Sie RAII bekommen):
CCriticalSection crit;
// Scope the objects
{
CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately.
// Do stuff which needs the lock (if IsLocked returns success)
CSingleLock lock2(&crit, TRUE);
// Do stuff which needs the lock (if IsLocked returns success)
}
// crit is unlocked now.
(Natürlich würden Sie niemals absichtlich zwei Sperren auf denselben kritischen Abschnitt in einem einzigen Block wie diesem erhalten. Das würde normalerweise nur durch den Aufruf von Funktionen passieren, die eine Sperre erhalten, während sie sich in etwas anderem befinden, das bereits seine eigene Sperre hat).
(Sie sollten auch CSingleLock.IsLocked überprüfen, um zu sehen, ob die Sperre erfolgreich war. Ich habe diese Prüfungen der Kürze halber weggelassen, und weil sie im Originalbeispiel nicht enthalten waren).
Wenn CCriticalSection selbst unter dem gleichen Problem leidet, dann ist das sicherlich ein Problem, aber er hat keinen Beweis dafür vorgelegt, den ich sehen kann. (Vielleicht habe ich etwas übersehen. Ich kann die Quelle zu CCriticalSection in meiner MFC-Installation nicht finden, um das zu überprüfen).