Auf meiner Linux-Box sig_atomic_t
ist einfach alt int
. Tun ints
besitzt eine besondere atomare Qualität?
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
...
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1)
$ echo '#include <signal.h>' | gcc -E - | grep atomic
typedef int __sig_atomic_t;
typedef __sig_atomic_t sig_atomic_t;
C99 sig_atomic_t
entspricht nur einer sehr schwachen Definition von “Atomizität”, weil C99 hat kein Konzept der Parallelität, nur Unterbrechbarkeit. (C2011 fügt ein Nebenläufigkeitsmodell hinzu, und damit die _Atomic
Typen, die stärkere Garantien geben; jedoch AFAIK sig_atomic_t
ist unverändert, da seine Daseinsberechtigung ist immer noch die Kommunikation mit Signalhandlern, nicht über Threads hinweg.)
Das ist alles, worüber C99 sagt sig_atomic_t
:
(§7.14 <signal.h>
Absatz 2) Der definierte Typ ist sig_atomic_t
, das ist der (möglicherweise flüchtig qualifizierte) ganzzahlige Typ eines Objekts, auf das als atomare Entität zugegriffen werden kann, selbst bei Vorhandensein von asynchronen Interrupts. (§7.14 <signal.h>
Absatz 2)
(§7.14p5) Wenn [a] Signal tritt anders als als Ergebnis des Aufrufs von auf abort
oder raise
-Funktion ist das Verhalten undefiniert, wenn der Signal-Handler auf ein beliebiges Objekt mit statischer Speicherdauer verweist, außer durch Zuweisen eines Werts zu einem als deklarierten Objekt volatile sig_atomic_t
.
(§7.18.3 Grenzwerte anderer Integer-Typen, Absatz 3) Wenn sig_atomic_t
(siehe 7.14) ist als vorzeichenbehafteter Integer-Typ definiert, der Wert von SIG_ATOMIC_MIN
darf nicht größer als −127 und der Wert von sein SIG_ATOMIC_MAX
darf nicht weniger als 127 sein; andernfalls ist sig_atomic_t als vorzeichenloser ganzzahliger Typ und der Wert von definiert SIG_ATOMIC_MIN
soll 0 und der Wert von sein SIG_ATOMIC_MAX
darf nicht weniger als 255 betragen.
Der Begriff “atomare Entität” ist nirgendwo im Standard definiert. Übersetzen von Standards-esisch, die Absicht ist, dass die CPU eine Variable vom Typ vollständig aktualisieren kann sig_atomic_t
im Speicher (“statische Speicherdauer”) mit einem Maschinenbefehl. Daher ist es in der parallelitätsfreien, präzise unterbrechbaren abstrakten C99-Maschine für einen Signalhandler unmöglich, eine Typvariable zu beobachten sig_atomic_t
Mitten in einem Update. Die §7.18.3p3-Sprachlizenzen für diesen Typ sind so klein wie möglich char
im Bedarfsfall. Beachten Sie bitte die völlige Abwesenheit jeder Sprache in Bezug auf prozessorübergreifende Konsistenz.
Es gibt echte CPUs, die mehr als eine Anweisung benötigen, um einen Wert größer als zu schreiben char
zur Erinnerung. Es gibt auch echte CPUs, die mehr als einen Befehl benötigen, um Werte zu schreiben kleiner als ein Maschinenwort (oft, aber nicht notwendigerweise dasselbe wie int
) in Erinnerung. Die Sprache im Handbuch der GNU C-Bibliothek ist jetzt ungenau. Es stellt den Wunsch der ursprünglichen Autoren dar, das zu eliminieren, was sie als unnötige Lizenz für C-Implementierungen betrachteten, um seltsamen Scheiß zu tun, der Anwendungsprogrammierern das Leben schwerer machte. Unglücklicherweise ist es genau diese Lizenz, die es möglich macht, C auf einigen echten Maschinen überhaupt zu haben. Es gibt mindestens einen Embedded-Linux-Port (zum AVR), für den beides nicht der Fall ist int
noch Zeiger können in einem Befehl in den Speicher geschrieben werden. (Es wird daran gearbeitet, das Handbuch genauer zu machen, siehe zB http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html — sig_atomic_t
scheint jedoch in diesem übersehen worden zu sein.)
Bestimmte Typen können mehrere Anweisungen zum Lesen/Schreiben erfordern. int
Typ wird immer atomar gelesen/geschrieben.
Datentyp: sig_atomic_t
Dies ist ein ganzzahliger Datentyp. Auf Objekte dieses Typs wird immer atomar zugegriffen.
In der Praxis können Sie davon ausgehen, dass int und andere Integer-Typen nicht länger als int atomar sind. Sie können auch davon ausgehen, dass Zeigertypen atomar sind; das ist sehr bequem. Beides gilt für alle Maschinen, die von der GNU-C-Bibliothek unterstützt werden, und für alle uns bekannten POSIX-Systeme.
Bezug
@ Chrisaycock: C? Gilt dies nicht für jede Sprache mit Zugriff auf
sig_atomic_t
Variablen? Ich hätte es genauso gut benutzen könneng++
.– smcdow
7. März 2012 um 18:55 Uhr
Das
sig_atomic_t
Typ ist eigentlich Teil der C-Spezifikation. Es ist auch in der C++-Spezifikation enthalten (wie die meisten Dinge), aber Sie erhalten am ehesten gute Antworten mit einem C-Tag.– Dietrich Ep
7. März 2012 um 19:31 Uhr
C garantiert das nicht. Bestimmte CPUs haben bestimmte Garantien für die Atomarität bestimmter Typen. Insbesondere moderne CPUs, die in Desktop-Systemen verwendet werden, neigen dazu, Atomarität zumindest für Alignment zu garantieren
int
s (dh Daten in Wortgröße der Plattform). Dies ist nicht unbedingt der Fall für ältere CPUs oder für CPUs, die in eingebetteten Systemen verwendet werden.– ninjalj
7. März 2012 um 19:59 Uhr