2009-04-01 2 views

Antwort

14

Vielleicht.

Es hängt vollständig von Ihrer Definition von "Atom" ab.

  • In einem einzigen Kern, tief eingebettet Umgebung ohne ein Betriebssystem beteiligt können Sie Interrupts normalerweise deaktivieren und aktivieren. Dies kann verwendet werden, um zu ermöglichen, dass eine Funktion gegen den Interrupt-Handler-Code atomar ist. Wenn Sie jedoch einen Multi-Master-Bus, eine DMA-Engine oder ein anderes Hardwaregerät haben, das unabhängig voneinander Speicher schreiben kann, ist selbst das Maskieren von Interrupts unter Umständen nicht stark genug.

  • In einer RTOS-Umgebung (Echtzeitbetriebssystem) stellt der Betriebssystemkernel normalerweise grundlegende Synchronisierungsgrundelemente wie kritische Abschnitte bereit. Ein kritischer Abschnitt ist ein Block von Code, der sich zumindest im Hinblick auf alle anderen kritischen Abschnitte "im Wesentlichen" atomar verhält. Es ist normalerweise grundlegend für die Implementierung anderer Synchronisationsprimitiven durch das Betriebssystem.

  • In einer Multi-Core-Umgebung ist oft eine Low-Level-Primitive namens Spinlock verfügbar. Es wird verwendet, um den Eintritt in einen Codeblock zu verhindern, der in Bezug auf andere Benutzer des gleichen Spinlock-Objekts atomar sein muss, und blockiert den wartenden CPU-Kern in einer engen Schleife, bis die Sperre aufgehoben wird (daher der Name).

  • In vielen Threading-Umgebungen werden komplexere Primitive wie Ereignisse, Semaphore, Mutexe und Warteschlangen vom Threading-Framework bereitgestellt. Diese arbeiten so mit dem Thread-Scheduler zusammen, dass Threads, die darauf warten, dass etwas passiert, überhaupt nicht laufen, bis die Bedingung erfüllt ist. Diese können verwendet werden, um die Aktionen einer Funktion in Bezug auf andere Threads, die das gleiche Synchronisationsobjekt verwenden, atomar zu machen.

  • Eine allgemeine Regel wäre die Verwendung der höchsten verfügbaren Funktionen in Ihrer Umgebung, die für die Aufgabe geeignet sind. Im besten Fall kann ein vorhandenes threadsicheres Objekt wie eine Nachrichtenwarteschlange verwendet werden, um zu vermeiden, dass irgendetwas in Ihrem Code überhaupt etwas Spezielles tun muss.

    1

    nicht portabel zumindest. Bei einigen Systemen können Sie sich dem wahrscheinlich annähern, indem Sie beispielsweise Interrupts von Maschinen ausschalten, um zu verhindern, dass der Kernel Ihre Funktion vorwegnimmt. Aber es wird sehr schwierig sein, besonders für nicht eingebettete Systeme.

    3

    Wenn Sie sicher, dass Ihre Funktion machen wollen, werden nicht durch das Signal unterbrochen werden, verwenden sigprocmask() Signale zu maskieren und demaskieren, obwohl einige Signale nicht blockiert werden kann (wie SIGKILL) und das Verhalten für einige Signale blockieren (wie SIGSEGV) ist nicht definiert .

    Weitere Informationen finden Sie unter man sigprocmask.

    1

    Sie benötigen plattformspezifische Unterstützung, um dies zu tun - entweder mithilfe von speziellen Compiler-Intrinsics für Hardware-Anweisungen oder mithilfe von Betriebssystemunterstützung. Weder C noch C++ haben standardisierte Synchronisationssachen.

    1

    Definieren Sie, was Sie mit 'atomar' meinen. Meinst du "atomar" in dem Sinne, dass bei der Ausführung deiner Funktion kein anderer Prozess oder Thread für die Zeitplanung ausgewählt wird?Oder meinst du, dass alle gemeinsam genutzten Objekte, die in deiner Funktion referenziert werden, nicht von anderen Threads verändert werden, während deine Funktion läuft?

    Für die ehemalige, können Sie nicht wirklich kontrollieren, dass aus dem Benutzerbereich. Wenn Sie sich auf einem Single-CPU-Rechner befinden, können Sie möglicherweise Atomizität garantieren, indem Sie Ihre Prozesspriorität auf die höchstmögliche Priorität erhöhen (aus dem Benutzerbereich). Aber selbst dann ist das nicht garantiert, da Ihr Planungsalgorithmus möglicherweise noch einen anderen Prozess ausführen kann. Die einzige zuverlässige Methode hierfür ist das Betriebssystem. Für einen Einzel-CPU-Rechner würden Sie Interrupts deaktivieren. Bei einer Multicore-Maschine müssen Sie den Bus sperren und warten, bis alle Prozesse auf anderen CPUs beendet sind. Die Frage ist hier: Warum möchten Sie Atomizität garantieren? Im Allgemeinen sollte die Anforderung, dass nur Ihr Prozess ausgeführt werden darf und keine anderen, nicht im Benutzerbereich vorhanden sein. Wenn Sie sicherstellen möchten, dass auf bestimmte Datenstrukturen nur jeweils ein Thread zugreift, sollten Sie eine portable Thread-Bibliothek verwenden (z. B. pthread) und Ihre Funktion als kritischen Abschnitt abgrenzen.

    1

    Wenn Sie atomar "nur einen Thread zu einer Zeit" meinen, können Sie die Funktion einfach mit einem Critical-Section-Block (in Windows) schützen. In Linux verwende ich ein Mutex-Lock/Unlock, um mehr oder weniger einen kritischen Abschnitt zu emulieren.

    0

    Sie könnten POSIX-Semaphoren, Mutexe oder ähnliches untersuchen, die unter Windows und Linux funktionieren könnten.

    Verwenden von z.B. cygwin oder minGW ist es sogar möglich, portablen Code zwischen Linux und Windows zu schreiben.

    Noch besser Sie Fenster Libs auf Linux erstellen: http://cdtdoug.blogspot.com/2009/05/mingw-cross-for-linux.html

    Verwandte Themen