3 Stimmen

Ist Ccriticalsection für die Produktion geeignet?

Wir sind ein paar Neulinge in der MFC und wir bauen eine Multi-threded Anwendung. Wir sind auf den Artikel in der URL gestoßen, der uns davor warnt, CCriticalSection zu verwenden, da seine Implementierung fehlerhaft ist. Wir möchten gerne wissen, ob jemand Erfahrungen mit CCriticalSection hat und ob er auf Probleme oder Bugs gestoßen ist? Ist CCriticalSection verwendbar und produktionsreif, wenn wir VC++ 2008 zur Erstellung unserer Anwendung verwenden?

http://www.flounder.com/avoid_mfc_syncrhonization.htm

thx

11voto

Leo Davidson Punkte 5905

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).

0voto

Arafangion Punkte 10934

Dieser Artikel legt nahe, dass eine einfache Situation, in der diese Primitive verwendet werden, in Ordnung ist, außer dass die Implementierung dieser Primitive gegen die Semantik verstößt, die von ihnen erwartet werden sollte.

Im Grunde genommen schlägt es vor, dass, wenn Sie es als nicht-rekursive Sperre verwenden, wo Sie darauf achten, immer sicherzustellen, dass die Sperre gültig ist (dh, nicht aufgegeben), dann sollten Sie in Ordnung sein.

In dem Artikel wird jedoch beklagt, dass die Einschränkungen unentschuldbar sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X