2017-03-08 2 views
0

Ich lerne gerade über gute und schlechte Praktiken in Bezug auf Multithreading. Nach meinem Verständnis ist es eine schlechte Übung, eine lokale Variable innerhalb eines Threads (t1) zu erstellen und einen Zeiger auf einen anderen Thread (t2) zu übergeben. Ich weiß, dass der Stapel von t1 dynamisch ist und t2 nicht immer auf die richtigen Daten zugreifen kann. Ist es jedoch möglich, dass, wenn t2 in diesen Zeiger schreibt, t2 den falschen Code ausführen könnte? Da diese Modifikation in t1's Stack stattfindet, kann es nur t1 richtig beeinflussen? Es sei denn natürlich, t2 hängt später von t1 ab. Wie kann ich über dieses Problem nachdenken? Oder hat jemand gute Informationen darüber, wie Pro-Thread-Stacks funktionieren?Probleme beim Erstellen von Variablen in Threads und beim Übergeben von Zeigern

Jede Hilfe geschätzt wird,

Dank!

+0

Die Antwort ist, dass es abhängt. Sie sind zwar berechtigt, Ihren eigenen Stack einem anderen Thread anzubieten, aber Sie sollten sich lieber vergewissern, dass Sie die Threads synchronisieren, um Race-Bedingungen zu vermeiden, einschließlich des Verhinderns, dass der Wert den Bereich verlässt, bis der andere Thread damit fertig ist. – paddy

Antwort

0

Der Stack für einen Thread ist nur ein Speicherbereich, der für diesen Thread reserviert wurde. Es ist jedoch einfach eine "konventionelle" Sache. Es gibt keine Durchsetzung dieser Trennung und der Bereich des Speichers wird tatsächlich von alle Threads geteilt. So

, wie @paddy kommentiert, sind Sie vollkommen frei, die Adresse einer lokalen Variablen von Thread A erstellt passieren jedoch einzufädeln B., müssen Sie nicht Rückkehr von der Erzeugungsfunktion in Gewinde A. Andernfalls Dieser Stapelspeicher wird (fast sicher) von jedem Thread wiederverwendet, den A als nächstes macht. (Es ist eine gute Idee, sicherzustellen, dass Sie verstehen, wie der Stack von Ihrer Sprache/Ihrem Compiler verwendet wird.)

Abgesehen davon ist die Synchronisierung des Werts in dieser Variablen genau dieselbe wie für jede andere Variable, die unter Threads geteilt wird.

Technisch gesehen ist es richtig, dass Thread B, der einfach in eine Variable auf Thread A's Stack schreibt, nichts direkt stören kann, was Thread B tut. Wenn Thread A jedoch von der Funktion zurückgibt, die die Variable erstellt hat, wird durch das Schreiben von Thread B im Wesentlichen ein Torpedo an einer "zufälligen" Position im Ausführungspfad von Thread A abgefeuert. Der Speicher könnte nun eine andere Variable in einer anderen Funktion enthalten, oder er könnte nun die Rücksprungadresse einer Funktion auf dem Stack von Thread A halten.

Da die Verfälschung von Thread A zu undefiniertem Verhalten in Ausführungspfad von Thread A führt, ist es extrem wahrscheinlich, dass es schließlich zu undefiniertem Verhalten/Beschädigung in Ausführungs-Pfad von Thread B führt (und alle anderen Threads).

Man denke nur über die möglichen Auswirkungen:

  • Wenn Sie das niederwertige Byte (s) eine Rückkehr Adresse ändern sind, Sie gehen Thread A zu veranlassen, zurückzukehren, was kann gut eine gültige Region des Codes, aber nicht der Code unmittelbar nach dem Funktionsaufruf, dass Thread A vor dem Schreiben ausgeführt wurde.

  • wenn Sie das mehr signifikante Bytes der Rücksendeadresse ändern enden, Thread A wahrscheinlich zu einem nicht ausführbaren Teil seiner virtuellen Adreßraum zurückzukehren ist (was wahrscheinlich zu einer Ausnahme und den Fehler des nehmen alle Threads runterladen).

  • Wenn Sie einen Variablenwert (oder einen gespeicherten Registerwert) ändern, nun, wer weiß, was das bedeutet?Es hängt vollständig von der Funktion, die beschädigt wird und was es war mit diesem Speicherort für. Sie könnten einen Array-Index in einen Out-of-Bounds-Wert oder einen Dateideskriptor ändern, um auf eine andere geöffnete Datei mit oder einen Gleitkommawert auf einen NaN-Wert zu verweisen. Oder einen Speicherpoolzeiger in einer durch Thread A aufgerufenen Bibliotheksroutine zu beschädigen. Oder Ändern eines Zeigerwerts, sodass er jetzt zurück in den Stapel von Thread B zeigt.

+0

Vielen Dank! Diese Erklärung war wirklich aufschlussreich, und das Beispiel des Stapels von Thread A, der eine Rückadresse an dieser Stelle enthielt, war ein starkes Beispiel. – ka123444

Verwandte Themen