Namespaces
Variants

Memory model

From cppreference.net

Definiert die Semantik der Computerspeicherung für den Zweck der C-Abstraktionsmaschine.

Der für ein C-Programm verfügbare Datenspeicher (Speicher) besteht aus einer oder mehreren zusammenhängenden Sequenzen von Bytes . Jedes Byte im Speicher hat eine eindeutige Adresse .

Inhaltsverzeichnis

Byte

Ein Byte ist die kleinste adressierbare Speichereinheit. Es ist definiert als eine zusammenhängende Folge von Bits, die groß genug ist, um jedes Element des basic execution character set zu halten ( die 96 Zeichen , die als Ein-Byte-Zeichen vorausgesetzt werden). C unterstützt Bytes mit Größen von 8 Bits und mehr.

Die Typen char , unsigned char und signed char verwenden jeweils ein Byte sowohl für die Speicherung als auch für die Wertdarstellung . Die Anzahl der Bits in einem Byte ist zugänglich über CHAR_BIT .

Für die Verwendung von Bytes zur Darstellung von Werten anderer grundlegender Typen (einschließlich Big-Endian- und Little-Endian-Speicherlayouts) siehe Objektdarstellung

Speicherort

Ein Speicherort ist

  • ein Objekt von skalarem Typ (arithmetischer Typ, Zeigertyp, Aufzählungstyp)
  • oder die größte zusammenhängende Folge von Bitfeldern mit nicht-null Länge
struct S
{
    char a;     // Speicherplatz #1
    int b : 5;  // Speicherplatz #2
    int c : 11, // Speicherplatz #2 (Fortsetzung)
          : 0,
        d : 8;  // Speicherplatz #3
    struct
    {
        int ee : 8; // Speicherplatz #4
    } e;
} obj; // Das Objekt 'obj' besteht aus 4 separaten Speicherplätzen

Threads und Datenrennen

Ein Ausführungsthread ist ein Kontrollfluss innerhalb eines Programms, der mit dem Aufruf einer Top-Level-Funktion durch thrd_create oder andere Mittel beginnt.

Jeder Thread kann potenziell auf jedes Objekt im Programm zugreifen (Objekte mit automatischer und thread-lokaler Speicherdauer können dennoch durch einen anderen Thread über einen Zeiger zugänglich sein).

Unterschiedliche Ausführungsthreads dürfen immer unterschiedliche Speicherbereiche gleichzeitig zugreifen (lesen und ändern), ohne Interferenz und ohne Synchronisierungsanforderungen. (Beachten Sie, dass es nicht sicher ist, zwei nicht-atomare Bitfelder in derselben Struktur gleichzeitig zu aktualisieren, wenn alle zwischen ihnen deklarierten Mitglieder ebenfalls (nicht-null-lange) Bitfelder sind, unabhängig von der Größe dieser dazwischenliegenden Bitfelder)

Wenn eine Auswertung eines Ausdrucks in einen Speicherbereich schreibt und eine andere Auswertung denselben Speicherbereich liest oder ändert, wird gesagt, dass die Ausdrücke konfligieren . Ein Programm, das zwei konfligierende Auswertungen hat, weist ein Datenrennen auf, es sei denn

Wenn ein Datenrennen auftritt, ist das Verhalten des Programms undefiniert.

(insbesondere ist mtx_unlock synchronized-with , und daher happens-before mtx_lock desselben Mutex durch einen anderen Thread, was es ermöglicht, Mutex-Sperren zum Schutz vor Datenrennen zu verwenden)

Speicherreihenfolge

Wenn ein Thread einen Wert aus einem Speicherbereich liest, kann er den Anfangswert, den Wert, der im selben Thread geschrieben wurde, oder den Wert sehen, der in einem anderen Thread geschrieben wurde. Siehe memory_order für Details zur Reihenfolge, in der Schreibvorgänge aus Threads für andere Threads sichtbar werden.

(seit C11)

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 3.6 Byte (S.: TBD)
  • 3.14 Speicherstelle (S.: TBD)
  • 5.1.2.4 Nebenläufige Ausführungen und Datenwettläufe (S.: TBD)
  • C17-Standard (ISO/IEC 9899:2018):
  • 3.6 Byte (p: TBD)
  • 3.14 Speicherstelle (p: TBD)
  • 5.1.2.4 Multithread-Ausführungen und Datenrennen (p: TBD)
  • C11-Standard (ISO/IEC 9899:2011):
  • 3.6 Byte (S. 4)
  • 3.14 Speicherstelle (S. 5)
  • 5.1.2.4 Nebenläufige Ausführungen und Datenwettläufe (S. 17-21)
  • C99-Standard (ISO/IEC 9899:1999):
  • 3.6 Byte (S.: 4)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 1.6 DEFINITIONEN VON BEGRIFFEN

Siehe auch

C++-Dokumentation für Speichermodell