Das Schlüsselwort „volatile“ in der Sprache C [duplicate]

Lesezeit: 5 Minuten

Ich habe ein Tutorial über volatile in der C-Sprache gelesen, aber ich kann es immer noch nicht herausfinden. Manche sagen das flüchtig teilt dem Compiler-Optimierer mit, dass Operationen, die diese Variable betreffen, nicht auf bestimmte Weise optimiert werden sollten. Dies bedeutet, dass immer dann, wenn der Wert einer Variablen in einem Register geändert wird, der Wert den Speicher beeinflussen sollte.

Und das sagen auch einige flüchtig bedeutet, dass der Wert außerhalb dieses Codes geändert werden kann.

Den zweiten Spruch kann ich nicht verstehen. Die flüchtige Variable kann also außerhalb dieses Codes geändert werden? Wie? Und sind diese beiden Aussagen beide richtig?

Die Aussage “der Wert kann außerhalb dieses Codes geändert werden” bedeutet im Grunde, dass ein anderes Programm oder eine andere Hardware diese Variable aktualisieren kann. Das ist absolut möglich. Eine Denkweise besteht darin, dieses Konzept auf eine Datei zu beziehen, die von mehreren Programmen gemeinsam genutzt wird. Eine Datei kann von vielen Programmen gleichzeitig geöffnet, geschrieben und gelesen werden. Wenn Sie aus einer Datei lesen, möchten Sie sicherstellen, dass Sie das neueste Update und nicht das älteste lesen.

Um auf das Schlüsselwort volatile zurückzukommen, bewirkt das Platzieren von volatile vor einer Variablen im Endeffekt dasselbe. Es stellt sicher, dass das, was Sie aus der Variablen auslesen, nicht auf der Optimierung des Compilers oder einer alten Kopie der Variablen Ihres Programms basiert. Außerdem sorgt das Schlüsselwort volatile dafür, dass die Variable bei jedem Zugriff aus dem Speicher geholt wird. Daher sind beide Aussagen in Bezug auf das Schlüsselwort volatile richtig.

  • Ich verstehe nicht, wie eine Hardware die Variable ändert? Bedeutet das, dass die Hardware keine Methode oder keinen Code benötigt, um die Variable zu ändern?

    Benutzer707549

    28. April 2011 um 17:30 Uhr

  • @ratzip: Ja. Eine Variable ist ein Ort im Speicher, der einen Wert enthält, und der Speicher ist nur ein Stück Hardware (z. B. ein RAM-Chip). Viele Computersysteme (Tastatur, Netzwerk, Audioeingang etc.) sind so eingerichtet, dass externe Hardware bestimmte Speicherplätze direkt verändern kann.

    – e.James

    28. April 2011 um 17:40 Uhr

Benutzeravatar von aviraldg
aviraldg

C ist nicht unbedingt für Computer. Wenn Sie zum Beispiel für den Game Boy Advance entwickeln, stoßen Sie oft auf Speicherplätze, die durch die Hardware modifiziert werden, also Sie dürfen die Variable nicht ändern in Ihrem Code, aber es wird trotzdem geändert. Das ist, was volatile meint.

Durch Hinzufügen der volatile Schlüsselwort, das sagst du dem Compiler “Der in dieser Variablen gespeicherte Wert (Speicherort) kann sich ohne ändern mein Code alles tun.”

  • Warum ist dies Teil des C-Standards und keine Erweiterung für diese Implementierungen – es gibt keine konforme Möglichkeit, eine Adresse zu erhalten, die auf einen Speicher zeigt, der sich so verhält.

    – Random832

    28. April 2011 um 17:12 Uhr

  • @Random: Weil es so ist. Wie auch immer, fast jede einzelne Plattform wird irgendwann mit Hardware interagieren müssen.

    – Oliver Charlesworth

    28. April 2011 um 17:14 Uhr


  • Auf bestimmten eingebetteten Plattformen – wie dem GBA haben Sie speicherabgebildete Register, sodass Sie mit Sicherheit wissen, dass sich eine bestimmte Region im Speicher befindet Wille benimm dich so.

    – aviraldg

    28. April 2011 um 17:15 Uhr


  • @Random: Kannst du das erklären? Sie glauben nicht, dass es möglich ist, angeschlossene Geräte anzuweisen, bestimmte Speicherorte als Puffer zu verwenden oder empfangene Signale zu übertragen?

    – Andreas Lazarus

    28. April 2011 um 17:16 Uhr


  • @Random: Der C-Standard definiert nicht wie #includes sollte auch gelöst werden. Das bedeutet nicht, dass sie nicht nützlich sind.

    – Oliver Charlesworth

    28. April 2011 um 17:32 Uhr

Benutzeravatar von Oliver Charlesworth
Oliver Charlesworth

Berücksichtigen Sie Folgendes:

  • eine Multithread-Anwendung,
  • eine Anwendung, die Shared Memory verwendet,
  • eine Anwendung, die auf einer Plattform läuft, die E/A-Register in den Adressraum abbildet,
  • eine Anwendung mit Hardware-DMA, die im Hintergrund abläuft.

In jeder dieser Situationen kann der Speicher außerhalb des aktuellen Threads geändert werden.

Beachten Sie, dass “Jedes Mal, wenn der Wert einer Variablen im Register geändert wird, sollte der Wert den Speicher beeinflussen“ ist richtig, nur nicht ganz klar.

  • und auch die beiden sprüche stimmen?

    Benutzer707549

    28. April 2011 um 17:19 Uhr

  • sondern volatile ist sehr, sehr selten nützlich für Multi-Thread-Code.

    – Neugieriger

    26. Oktober 2011 um 22:53 Uhr

  • volatile ist auch im Fall von Daten nützlich, die durch ein asynchrones Ereignis modifiziert werden könnten, wie z. B. die Ausführung von Signal-Handler-Code (dh der Signal-Handler-Code hat die Variable geändert).

    – vyudh

    9. April 2013 um 2:35 Uhr

  • In der C-Spezifikation gibt es keine Anforderung, dass volatile eine Acquir/Release-Semantik oder eine andere Semantik haben muss, die für Multithread-Code tatsächlich nützlich ist. Denken Sie daran, dass möglicherweise verschiedene Threads mit inkonsistenten Caches auf verschiedenen Prozessoren arbeiten. Es ist nicht erforderlich, dass ein Compiler volatile implementiert, um dies zu berücksichtigen. Wenn Sie keinen Code für einen bestimmten Compiler schreiben und wissen, welche Erweiterungen der C-Sprache der Compiler in Bezug auf volatile implementiert, sollten Sie volatile nicht für die Threading-Semantik verwenden.

    – Eric Lippert

    10. Juni 2014 um 16:42 Uhr

  • @EricLippert: Es gibt auch keine Anforderung im C-Standard, dass eine konforme Implementierung für irgendeinen Zweck geeignet sein muss. Die Tatsache, dass der Standard nicht verlangt, dass eine konforme Implementierung etwas tut, bedeutet in keiner Weise, dass Qualitätsimplementierungen, die für Low-Level-Programmierung geeignet sein sollen, dies nicht tun sollten. Leider ist es für Compiler in Mode, Probleme mit der Qualität der Implementierung als Entschuldigung für die Implementierung von Semantik schlechter Qualität zu behandeln.

    – Superkatze

    13. Juli 2018 um 22:33 Uhr

Ein Speicherplatz kann außerhalb eines Programmcodes auf sehr viele Arten geändert werden. Beispielsweise kann ein DMA-Lesevorgang von einer Platte in einen Puffer schreiben, oder ein speicherabgebildetes Gerät kann aufgrund eines Ereignisses auf dem Gerät einen Speicherort ändern.

Benutzeravatar von Flinsch
Flinsch

Dies adressiert beispielsweise Multithread-Anwendungen: Der Wert einer Variablen kann von mehreren Threads geändert werden und muss daher bei jedem Zugriff (egal ob Lesen oder Schreiben des Werts) mit dem Speicher „synchronisiert“ werden.

  • volatile ist sehr, sehr selten nützlich für Multi-Thread-Code.

    – Neugieriger

    26. Oktober 2011 um 22:53 Uhr

Benutzeravatar von Peter Mortensen
Peter Mortensen

Das Deklarieren einer flüchtigen Variablen bedeutet, dass Sie den Compiler anweisen, das Code-Snippet nicht um diese Variable herum zu optimieren. Dies soll die CPU dazu zwingen nicht den Variablenwert aus lokalen Registern oder Cache-Speicher zu verwenden, aber den Wert jedes Mal aus dem Hauptspeicher zu holen.

  • volatile ist sehr, sehr selten nützlich für Multi-Thread-Code.

    – Neugieriger

    26. Oktober 2011 um 22:53 Uhr

1438050cookie-checkDas Schlüsselwort „volatile“ in der Sprache C [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy