Laut Herb Sutter (http://isocpp.org/blog/2012/12/you-dont-know-const-and-mutable-herb-sutter) dürfen in C++ 11 const-Methoden das Objekt nicht bitweise ändern oder müssen eine interne Synchronisation durchführen (z. B. mit einem Mutex), wenn sie veränderliche Datenelemente haben.Wenn C++ konstante Methoden den veränderbaren Zustand synchronisieren, müssen auch nichtkonstante Methoden dies tun?
Meine Frage ist, müssen nicht-const Methoden den Mutex auch erwerben? Oder können sie sich auf die externe Synchronisierung verlassen, die ihr Benutzer ausführen muss, wenn der Benutzer gleichzeitig konstante und nicht konstante Methoden für dasselbe Objekt mischen will?
EDIT: Anders gesagt,
ist die folgende Klasse Thread-Safe?
bietet die folgende Klasse Sutters "grundlegende Thread-Sicherheitsgarantie" (von part 4b of GOTW #95)?
#include <thread>
class C {
public:
void const_method() const
{
std::lock_guard<std::mutex> g(m);
i = 2;
}
void non_const_method()
{
// std::lock_guard<std::mutex> g(m); // <-- is this needed?
i = 1;
}
private:
mutable int i;
mutable std::mutex m;
};
Wie könnten mehrere Threads gleichzeitig "i" ändern? Die einzige Funktion, die rechtlich gleichzeitig aufgerufen werden kann, ist "const_method", und sie erhält eine Sperre. (Code, der 'non_const_method' gleichzeitig aufruft, wäre nicht Thread-sicher, aber es gibt keinen solchen Code in der Klasse.) –
@DavidSchwartz:" * Die einzige Funktion, die gleichzeitig gleichzeitig aufgerufen werden kann, ist const_method, * "Und deshalb Die Klasse ist nicht threadsicher. Der Punkt, den Herb macht, ist, dass "konstante" Methoden immer threadsicher sein sollten.Nicht-konstante Methoden können Thread-sicher sein oder auch nicht, abhängig von den Launen des Klassenimplementierers. Die Verwendung von 'const'-Methoden threadsicher bedeutet nicht, dass der gesamte Typ threadsicher ist (es sei denn, seine einzigen Verwendungen verwenden' const'-Methoden). –
@NicolBolas Es bedeutet, dass der gesamte Typ Thread-sicher ist, solange nicht zwei nicht konstante Methoden der gleichen Instanz der Klasse gleichzeitig aufgerufen werden. Aber dann wäre es der Code, der die beiden nichtkonstanten Methoden zur gleichen Zeit aufgerufen hat, die nicht Thread-sicher waren, nicht die Klasse. Eine Klasse ist threadsicher, wenn sie vorhersehbares Verhalten bietet, wenn sie in Multithread-Code verwendet wird, der nicht gegen den Schnittstellenvertrag verstößt. Der übliche Schnittstellenvertrag ist "keine gleichzeitigen Zugriffe auf nicht-konstante Methoden auf derselben Instanz". Jede Klasse macht schlechte Sachen, wenn Sie ihren Schnittstellenvertrag verletzen. –