Benötige ich Mutex im Konstruktor für das Feld?

8

Nehmen wir an, ich habe eine einfache Klasse A mit einem Feld in C ++. Dieses Feld wird im Konstruktor initialisiert. Klasse A hat auch eine Methode namens doit() , um den Wert dieses Feldes zu ändern. doit() wird von mehreren Threads aufgerufen. Wenn ich einen Mutex nur in der doit() -Methode habe, ist das ausreichend? Habe ich eine Garantie, dass ich nie ein nicht initialisiertes Feld lesen werde (weil es im Konstruktor keine Sperre gibt)?

Bearbeiten: Ich war wahrscheinlich nicht klar genug. Gibt es kein Problem mit Prozessor-Cache oder ähnlichem? Ich meine, wenn es keinen Mutex zum Initialisieren des Speicherbereichs gibt (d. H. Mein Feld) - besteht kein Risiko, dass der andere Thread einen Müllwert liest?

    
kgs 12.10.2012, 10:34
quelle

3 Antworten

7

Ihr Objekt kann nur einmal initialisiert werden, und Sie können es nicht benutzen, bevor es initialisiert wird, also brauchen Sie dort keinen Mutex. Sie werden jedoch einen Mutex oder eine andere geeignete Sperre in Ihrer Funktion DoIt benötigen, da Sie darauf hingewiesen haben, dass auf mehrere Threads zugegriffen wird.

Update für bearbeitete Frage: Nein, Sie müssen sich keine Gedanken über den Prozessor-Cache machen. Sie müssen zuerst Ihr Objekt konstruieren, bevor Sie es handhaben können. Nur wenn Sie dieses Handle haben, können Sie es an andere Threads weitergeben, die verwendet werden sollen. Was ich sagen will, ist, dass die erzeugten Threads nach der Konstruktion des ursprünglichen Objekts starten müssen, es ist unmöglich, dass es umgekehrt passiert!

    
Mark Ingram 12.10.2012, 10:42
quelle
2

Es ist nicht möglich, doit() für ein Objekt aufzurufen, das noch nicht erstellt wurde, sodass Sie im Konstruktor keinen Mutex benötigen.

Wenn doit() die einzige Methode ist, die auf das Feld zugreift, sollten Sie in Ordnung sein.

Wenn andere Methoden Ihrer Klasse auch aus einem einzelnen Thread auf dieses Feld zugreifen, müssen Sie auch in diesen Methoden einen Mutex verwenden.

    
Gildas 12.10.2012 10:45
quelle
0
  1. Sie müssen zuerst das Objekt konstruieren, bevor diese lästigen Fäden in die Hände bekommen. Das Betriebssystem reserviert Speicher für den Konstruktor, der nur von einem Thread aufgerufen wird. Das Betriebssystem kümmert sich um diese Zuordnung und daher muss nichts von Ihnen getan werden. Hölle Sie können sogar zwei Objekte der gleichen Klasse in zwei verschiedenen Threads erstellen.
  2. Sie können sehr konservativ sein und einen Mutex zu Beginn jeder Methode verwenden, die dieses Feld verwendet hat, um es zu sperren und es und das Ende freizugeben.

Wenn Sie die Interaktionen der verschiedenen Methoden mit den verschiedenen Algorithmen verstehen, können Sie einen Mutex für kritische Abschnitte verwenden Code, der dieses Feld verwendet - dh dieser Teil des Codes muss sicher sein, dass das Feld während der Verarbeitung nicht von einem anderen Thread geändert wird, aber Ihre Methode kann die Sperre nach dem kritischen Abschnitt freigeben, etwas anderes tun und dann möglicherweise einen anderen kritischen Abschnitt haben .

    
Ed Heal 12.10.2012 12:11
quelle

Tags und Links