C++ char variablen threadsafe?



  • Hi,

    ich schreibe gerade ein kleines Programm und muss mir nun auch Gedanken über die "threadsafeness" machen. Ich könnte natürlich mutex benutzen, aber dann ist mir aufgefallen, dass alle Variablen, welche über mehrere Threads hinweg benutzt werden im Grunde nur 1 Byte groß sein müssten. Sind diese nicht immer threadsafe? Weniger als 1 Byte kann der Prozessor ja eh nicht verändern.

    Gruß



  • Definier doch mal threadsafe.



  • Der Standard kennt keine Threads. (EDIT: Hier meinte ich den C++03 Standard)

    Du kannst afaik zum Beispiel Probleme mit Caching erhalten.

    Falls du C++0x verwendest könntest du ein std::atomic<char> in Erwägung ziehen.

    Aber mal eine andere Frage... Wofür brauch man ein threadsicheres char?

    Gruß,
    XSpille



  • Aber mal eine andere Frage... Wofür brauch man ein threadsicheres char?

    Zb. um den Zustand eines Tasks zu markieren.



  • Ethon schrieb:

    Aber mal eine andere Frage... Wofür brauch man ein threadsicheres char?

    Zb. um den Zustand eines Tasks zu markieren.

    Seit wann codiert man Zustände in Buchstaben? 😮
    Also ich nehme für Zustände enums bzw. int 🙄



  • XSpille schrieb:

    Seit wann codiert man Zustände in Buchstaben? 😮

    Chars müssen nicht unbedingt Buchstaben sein.
    @OP: je nachdem, was für Zustände und Tasks es sind, sind vielleicht auch futures eine Möglichkeit, die Kommunikation über den Zustand der Bibliothek zu überlassen.



  • pumuckl schrieb:

    XSpille schrieb:

    Seit wann codiert man Zustände in Buchstaben? 😮

    Chars müssen nicht unbedingt Buchstaben sein.

    Hast du natürlich recht... Aber nimmst du da chars?



  • XSpille schrieb:

    pumuckl schrieb:

    XSpille schrieb:

    Seit wann codiert man Zustände in Buchstaben? 😮

    Chars müssen nicht unbedingt Buchstaben sein.

    Hast du natürlich recht... Aber nimmst du da chars?

    Nein, würde ich komplett anders regeln. Aber wenns mir um Platzersparnis ginge und ich einen konformen C++11-Compiler hätte, würde ich ein enum auf (unsigned) char-Basis nehmen 😉



  • pumuckl schrieb:

    Aber wenns mir um Platzersparnis ginge und ich einen konformen C++11-Compiler hätte, würde ich ein enum auf (unsigned) char-Basis nehmen 😉

    Das C++11-Feature Strongly typed enumerations hatte ich auch noch nicht zur Kenntnis genommen 🙂
    Falls es jemand nicht kennt: http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations

    Danke für die Info pumuckl 👍



  • XSpille schrieb:

    Ethon schrieb:

    Aber mal eine andere Frage... Wofür brauch man ein threadsicheres char?

    Zb. um den Zustand eines Tasks zu markieren.

    Seit wann codiert man Zustände in Buchstaben? 😮
    Also ich nehme für Zustände enums bzw. int 🙄

    Naja, aussagekräftige Buchstaben sind aber auch nicht umbedingt verkehrt.



  • Mir geht es echt darum, dass verschiedene threads auf gloable Variablen zugreifen können. Den char hatte ich nur genommen, weil er 8 Bit groß ist und somit mein Schreib oder Lesezugriff ja am ehesten atomar sein müsste. Mein Frage ist nun wie ich diesen Schreib oder Lesezugriff threadsafe hinbekomme. Einen Mutex benutzen dürfte doch eigentlich nicht reichen, oder? Dann habe ich zwar gesichert, dass niemals Threads gleichzeitig das Object lesen oder schreiben, aber ich muss doch noch sicherstellen, dass die Veränderungen auch immer übernommen werden. Also das Object auch noch volatile machen.



  • Das wird durch die Verwendung eines Mutex garantiert. Ich würde dennoch atomics nehmen, da die vermutlich günstiger sind.



  • Aber woher weiß der Mutex denn welche Variablen ich verändert haben und vorallem woher weiß ein anderer Thread, dass die Variable von außen verändert werden kann? Muss da nicht ein volatile verwendet werden?

    Das gleiche gilt doch im Grunde für die atomics. Auch wenn all meine Zugriffe atomar sind müssen doch alle threads wissen, dass sie immer die Variable bei jedem check neu einlesen müssen.



  • Andere Threads sehen deinen Wert doch nur nicht, wenn der Write Back (Zurückschreiben des Wertes in den Speicher) noch nicht stattgefunden hat. Bei atomics passiert dies direkt, wie das bei Mutexen ist, weiß ich nciht so genau. Aber ich weiß, dass es funktioniert (und nicht nur "funktioniert" sondern auch richtig ist so.)



  • ?

    Kurze Aufklärung wie ein Mutex funktioniert: Wenn du eine Operation machen möchtest, die threadsicher sein muss, dann erzeugst du mit einer Betriebssystem-API (oder seit C++11 auch std::mutex) ein Mutex-Objekt, das sich alle Threads teilen. Das macht erstmal überhaupt nichts.
    Wenn du jetzt in den kritischen Bereich kommst, sperrst du den Mutex (OS-API bzw std::mutex::lock). Hat bereits ein anderer Thread den Mutex gelockt, wird blockiert und gewartet. Ab diesem Punkt verrichtest du deine Arbeit und gibst so schnell als möglich den Mutex wieder frei, damit andere Threads auch in diesem Bereich arbeiten können.

    Die atomics werden warscheinlich als Fallback mit einem Mutex implementiert, aber praktisch jeder moderne Prozessor bietet einen Befehl zum atomaren lesen/schreiben von Werten. Dieser wird in der Regel genutzt und das Ganze ist verglichen mit einem Mutex höllisch schnell.



  • threadter schrieb:

    Das gleiche gilt doch im Grunde für die atomics. Auch wenn all meine Zugriffe atomar sind müssen doch alle threads wissen, dass sie immer die Variable bei jedem check neu einlesen müssen.

    Na dafür gibt es ja die acquire/release/... Semantik.
    Damit sagst du, was du gerne haben möchtest.
    Also ob du Änderungen anderer Threads sehen möchtest, oder aber deine Änderungen "in den Speicher zurückschreiben", oder beides, oder gar nix oder...

    PS: ich würde trotzdem empfehlen Mutexen zu verwenden. Weil die viel einfacher richtig zu verwenden sind.


Anmelden zum Antworten