Ich habe ein Problem, das scheint mir beunruhigend. Es scheint, dass ich eine Situation gefunden habe, die leicht genug ist, um zu arbeiten, aber das könnte zu Problemen führen, wenn a) ich beim Programmieren eine Konzentrationsstörung habe oder b) jemand anders meine Interfaces implementiert und nicht weiß, wie ich damit umgehen soll diese Situation.Vermeiden Sie Deadlock mit nicht-virtuellen öffentlichen Schnittstelle und Scoped Locks in C++
Hier ist meine Grundeinstellung:
ich eine abstrakte Klasse habe, die ich als eine generische Schnittstelle zu mehreren Datentypen verwenden. Ich habe das Paradigma der nicht-virtuellen öffentlichen Schnittstelle (Sutter, 2001) zusammen mit dem Scoped-Locking übernommen, um eine gewisse Thread-Sicherheit zu bieten. Ein Beispiel Interface-Klasse würde wie folgt aussehen (ich habe weggelassen Details über scoped Schließ- und der Mutex Implementierung, da ich nicht glaube, sie sind relevant):
class Foo
{
public:
A()
{
ScopedLock lock(mutex);
aImp();
}
B()
{
ScopedLock lock(mutex);
bImp();
}
protected:
aImp() = 0;
bImp() = 0;
}
Es liegt dann an den Benutzer . zu implementieren AIMP und BIMP, das ist, wo das Problem kommt Wenn AIMP eine Operation durchführt, die BIMP verwendet, ist es extrem leicht ist (und fast logisch, in gewissem Sinne), dies zu tun:
class Bar
{
protected:
aImp()
{
...
B();
...
}
bImp()
{
...
}
}
Deadlock. Natürlich besteht die einfache Lösung darin, immer die geschützten virtuellen Funktionen und nicht ihre öffentlichen Varianten aufzurufen (ersetzen Sie B() durch bImp() im obigen Snippet). Aber es scheint mir immer noch viel zu leicht zu sein, mich selbst aufzuhängen, wenn ich einen Fehler begehe, oder schlimmer noch, anderen zu erlauben, sich aufzuhängen.
Gibt es jemanden, der versucht, einen Implementierer der abstrakten Klasse daran zu hindern, diese öffentlichen Funktionen zur Kompilierungszeit aufzurufen oder die Deadlock-Lösung zu vermeiden?
Nur für den Kick, ermöglichen einige Mutexe Betrieb, die Deadlock-Probleme zu vermeiden. Wenn ich dies beispielsweise mit den Windows-Funktionen EnterCriticalSection und LeaveCriticalSection implementiere, gibt es kein Problem. Aber ich würde eher plattformspezifische Funktionalität vermeiden. Ich benutze derzeit boost :: mutex und boost :: shared_mutex in meiner Scoped-Lock-Implementierung, und soweit ich gesehen habe, versuche ich nicht Deadlock zu vermeiden (was ich glaube, ich bevorzuge es fast).
Eine weitere Sutter-Empfehlung: "Vermeiden Sie den Aufruf virtueller Methoden" in "Vermeiden Sie den Aufruf unbekannter Codes in einem kritischen Bereich" (http://www.ddj.com/architect/202802983). –
Danke für den Link. Ich werde das jetzt lesen. – Perculator