Share via


_ReadWriteBarrier

Microsoft-spezifisch

Erzwingt liest und schreibt in den Speicher, um zum Zeitpunkt des Aufrufs abzuschließen.

WarnhinweisVorsicht

_ReadBarrier, _WriteBarrier und _ReadWriteBarrier systeminterne Funktionen des Compilers Compiler verhindern, dass nur neu anordnen.Um die CPU am Neuanordnung gelesen und an den Schreibvorgängen zu verhindern, verwenden Sie das Makro MemoryBarrier.

void _ReadWriteBarrier(void);

Anforderungen

Intrinsisch

Architektur

_ReadWriteBarrier

x86, IPF, x64

Headerdatei <intrin.h>

Hinweise

_ReadBarrier, _WriteBarrier und Funktionen _ReadWriteBarrier den korrekten Ausführung von Multithreading Programmen sichergestellt werden, die vom Visual C++ Compiler optimiert werden.Ein ordnungsgemäß optimiertes Programm führt dieselben Ergebnisse, wenn sie in mehreren Threads z. B. ausführt, wenn es auf einem einzigen Thread ausgeführt wird.

Der Punkt in einer Anwendung, an dem _ReadBarrier, _WriteBarrier oder _ReadWriteBarrier-Funktion ausführt, wird eine Arbeitsspeicher barriere aufgerufen.Eine Arbeitsspeicher barriere kann für das liest, Schreib- oder beides.

Eine Anweisung, die eine Variable im Arbeitsspeicher zugreift, würde zu einer Arbeitsspeicher barriere als Teil einer Optimierung gelöscht oder verschoben werden.Daher läse ein Thread einen alten Wert aus einer globalen Variablen, bevor ein anderer Thread Schreiben eines neuen Werts in die Variable schreiben oder Abschluss eines neuen Werts, bevor ein anderer Thread das Lesen eines alten Wert der Variablen durchführen können.

Um sicherzustellen, dass das optimierte Programm ordnungsgemäß funktioniert, erzwingt die _ReadWriteBarrier-Funktion liest und schreibt in den Speicher um zum Zeitpunkt des Aufrufs abzuschließen.Nach dem Aufruf können andere Threads den Arbeitsspeicher, ohne Furcht zugreifen, dass der Thread, der den Aufruf ausgeführt wurde, ein ausstehendes Lesen verfügen oder den Speicher schreibt.Eine Arbeitsspeicher barriere verhindert, dass Speicherzugriffe der Compiler optimiert, jedoch oberhalb der Grenze ermöglicht es dem Compiler, um Anweisungen zwischen Barrieren weiter zu optimieren.

Markierungs Arbeitsspeicher mit einer Arbeitsspeicher barriere entspricht dem Markieren des Speichers mit dem flüchtig (C++)-Schlüsselwort ähnlich.Dennoch ist eine Arbeitsspeicher effizienter, da barriere erzwungen werden, um an bestimmten Stellen im Programm anstelle von globalen Lese- und Schreibvorgänge auszuführen.Die Optimierungen, die auftreten können, wenn eine barriere Arbeitsspeicher verwendet wird, kann nicht auftreten, wenn die Variable flüchtigen Stoff deklariert ist.

HinweisHinweis

In früheren Versionen von Visual C++ Compilers _ReadWriteBarrier wurden, und die _WriteBarrier Features nur lokal erzwungen und keine Funktionen in der Aufrufstruktur betreffen.Diese Funktionen sind jetzt alle in der Aufrufstruktur erzwungen.

Betroffener Arbeitsspeicher

Globale Variablen sind im Arbeitsspeicher barrieren beeinflusst, aber in der Regel lokale Variablen sind nicht möglich.Die meisten lokalen Variablen sind nicht an andere Threads zugegriffen werden. Daher erfordern keine Schutz.Eine Variable wird durch eine Arbeitsspeicher barriere betroffen, wenn sie eine der folgenden Bedingungen erfüllt:

  • Die Variable ist eine globale Variable.

  • Die Variable ist eine lokale Variable, die in __try, __except oder __finally-Block verwendet wird, wenn die strukturierte Ausnahmebehandlung verwendet wird, oder ein catch-Block, wenn die C++-Ausnahmebehandlung verwendet wird.Weitere Informationen finden Sie in der /EHa-Compileroption.

  • Die Variable ist eine lokale Variable, die volatile deklariert ist.

  • Die Variable ist eine lokale Variable, deren Adresse die aktuelle Funktion auf eine Weise versieht.Beispielsweise wird die Variable mit Hinweis auf eine andere Funktion übergeben oder seine Adresse wird einer globalen Variablen zugewiesen.

  • Die Variable wird indirekt über einen Zeiger darauf zugegriffen, und der dereferenzierte Zeiger erfüllt eine der vorherigen Bedingungen.Der gängigste Fall ist *p, in dem p eine globale Variable oder einen Parameter handelt.

Beispiel

// intrinsics_readwritebarrier.c
// compile with: /O2 -DNO_BARRIER
// This code contains an error--dereferencing a null pointer--
// which will be optimized away as a useless assignment.
// Omit the NO_BARRIER command line to activate the Write Barrier.
// With the barrier activated, the assignment is not optimized away
// and causes an access violation.

#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
#include <stdio.h>
#include <intrin.h>

#pragma intrinsic(_ReadWriteBarrier)

int x = 0;

__declspec(noinline) int f(int* p)
{
    x = *p;
#ifndef NO_BARRIER
    _ReadWriteBarrier();
#endif
    x = 7;
    return x;
}


// If code is EXCEPTION_ACCESS_VIOLATION it means an
// attempt to read from the NULL pointer we passed in, so
// we handle the exception.
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
    if (code == EXCEPTION_ACCESS_VIOLATION)
    {
        printf_s("AV\n");
        return EXCEPTION_EXECUTE_HANDLER;
    }

    // If not what we were looking for, we don't want to handle it.
    return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
    int nRet = 0;

    __try
    {
        // Should return only if the first assignment is
        // optimized away.
        nRet = f(NULL);
        printf_s("Assignment was optimized away!\n");
    }
    __except(filter(GetExceptionCode(), GetExceptionInformation()))
    {
        // We get here if an Access violation occurred.
        printf_s("Access Violation: assignment was not optimized away.\n");
    }
}
  

Siehe auch

Referenz

_ReadBarrier

_WriteBarrier

Systeminterne Funktionen des Compilers

C++-Schlüsselwörter