Was heisst Thread-Safe?
-
Deine Aufzählung ist doof. Aus Nummer 2 folgt Nummer 1 unweigerlich. Das ändern der Objekte in der Liste stellt jedoch kein Problem dar.
-
bei thread safe gehts nicht ueber "duerfen" oder "nicht duerfen", sondern darum, dass es ein vorherbestimmtes verhalten gibt wenn mehrere threads sich daten teilen.
wenn also deine liste "thread safe" ist, dann duerfen mehrere threads drauf arbeiten.
manchmal gibt es auch abstufungen von "thread safe", dass z.B. die anzahl der threads limitiert ist, oder das verhalten (lesen/schreiben/modifizieren).
-
xscdvfbg schrieb:
µ schrieb:
Verlink halt den Wikiartikel zu Thread safety ... vielleicht taugt der ja was.
http://en.wikipedia.org/wiki/Thread_safety
Aber eigentlich ist relativ unklar, wo Thread safety aufhört.
Wenn man z.B. ne Liste mit Objekten hat und über diese iteriert, was sollen dann andere threads nicht dürfen?
- Den Iterator ungültig machen?
- Die Liste verändern?
- Die Objekte in der Liste verändern?
in dem fall doch recht eindeutig, den gesamten code für die iteration nicht ausführen bevor der andere thread fertig damit ist. Wenn er objekte in der liste verändert muss ja beliebiger zugriff auf ein beliebiges listenelement geschützt sein, wenn die liste verändert wird(size, oder neues element eingefügt) würde das mit der iteration des anderen threads interferieren, und den iterator ungültig machen, den der entsprechende thread für seine eigene iteration neu deklariert hat (auf seinem stack), dürfte doch egal sein bzw unsinnig wenn man iterieren will.
Dazu noch, wann ist es ok dass ein thread bei stelle 20 entweder ein neues element einfügt, oder ein bestehendes element verändert, während der andere thread bereits bei element 50 angelangt ist und das veränderte/neue Element damit nie gesehen hat?
Also in dem Fall, auf einer niedrigeren Ebene als der kompletten Iteration thread-safety garantieren ergibt doch nicht viel Sinn oder?
-
Kontrasubjekt schrieb:
in dem fall doch recht eindeutig, den gesamten code für die iteration nicht ausführen bevor der andere thread fertig damit ist. Wenn er objekte in der liste verändert muss ja beliebiger zugriff auf ein beliebiges listenelement geschützt sein, wenn die liste verändert wird(size, oder neues element eingefügt) würde das mit der iteration des anderen threads interferieren, und den iterator ungültig machen, den der entsprechende thread für seine eigene iteration neu deklariert hat (auf seinem stack), dürfte doch egal sein bzw unsinnig wenn man iterieren will.
Dazu noch, wann ist es ok dass ein thread bei stelle 20 entweder ein neues element einfügt, oder ein bestehendes element verändert, während der andere thread bereits bei element 50 angelangt ist und das veränderte/neue Element damit nie gesehen hat?
Also in dem Fall, auf einer niedrigeren Ebene als der kompletten Iteration thread-safety garantieren ergibt doch nicht viel Sinn oder?Ja, und darum halte ich solche Aussagen
rapso schrieb:
wenn also deine liste "thread safe" ist, dann duerfen mehrere threads drauf arbeiten.
für gefährlich. Die hören sich so an, als ob die Liste mehr bietet, als sie kann. Die Liste ansich mag zwar nicht kaputt gehen, aber der Inhalt der Liste muss nicht immer für alle konsistent sein, wenn mehrere Threads wild darauf rum arbeiten.
-
xscdvfbg schrieb:
Kontrasubjekt schrieb:
in dem fall doch recht eindeutig, den gesamten code für die iteration nicht ausführen bevor der andere thread fertig damit ist. Wenn er objekte in der liste verändert muss ja beliebiger zugriff auf ein beliebiges listenelement geschützt sein, wenn die liste verändert wird(size, oder neues element eingefügt) würde das mit der iteration des anderen threads interferieren, und den iterator ungültig machen, den der entsprechende thread für seine eigene iteration neu deklariert hat (auf seinem stack), dürfte doch egal sein bzw unsinnig wenn man iterieren will.
Dazu noch, wann ist es ok dass ein thread bei stelle 20 entweder ein neues element einfügt, oder ein bestehendes element verändert, während der andere thread bereits bei element 50 angelangt ist und das veränderte/neue Element damit nie gesehen hat?
Also in dem Fall, auf einer niedrigeren Ebene als der kompletten Iteration thread-safety garantieren ergibt doch nicht viel Sinn oder?Ja, und darum halte ich solche Aussagen
rapso schrieb:
wenn also deine liste "thread safe" ist, dann duerfen mehrere threads drauf arbeiten.
für gefährlich. Die hören sich so an, als ob die Liste mehr bietet, als sie kann. Die Liste ansich mag zwar nicht kaputt gehen, aber der Inhalt der Liste muss nicht immer für alle konsistent sein, wenn mehrere Threads wild darauf rum arbeiten.
wenn eine liste thread safe ist, bedeutet das ja auch nicht zwangsweise, dass sie fuer alle konsistent ist, das impliziert thread safe garnicht. du kannst auch innerhalb vom selben thread eine funktion aufrufen die als nebenwirkung ueber umwege auf die liste zugreift und elemente einfuegt/entfernt und eventuell sogar den iterator invalidiert, natuerlich, aber deswegen wuerde auch niemand sagen die implementation der liste ist buggy, sondern die verwendung. entsprechen ist eine liste die thread safe ist, eine die beim zugriff durch mehrere threads weiterhin funktioniert.
es geht bei dem ganzen eher um den ausschluss des gegenteils, wenn eine liste nicht thread safe ist, dann darfst du sie in keinem fall aus mehreren threads verwendet und muss thread-sicherheit drumherum bauen.
normalerweise gibt man auch an, in welcher weise etwas threadsafe ist, es geht beim ganzen ja nicht nur um stabilitaet (wobei das natuerlich an vorderster stelle steht wenn man "safe" sagt), es geht auch ums laufzeitverhalten, etwas threadsafe zu machen, indem man alle anderen threads schlafen laegt ist auch tod sicher und dennoch meist nicht gewuenscht. (oh, und das ist kein absurdes beispiel, das einzige paper im web ueber eine wait-free list implementierung die ich fand, fuer beliebiger anzahl von threads, ist fuer ein echtzeit OS, bei dem, waehrend des zugrifs auf die liste, die thread priority so hochgestellt wird, dass kein anderer thread drankommt, dadurch ist die liste waitfree... das paper muss man zudem kaufen
).
-
Okay, kann man dann sagen wenn die einzelnen Threads zum Beispiel nur read-Rechte haben, ist eine struct oder ein einfaches array thread-safe? Auch wenn einige 100 Threads darauf zugreifen?
Wenn die Write-Rechte dann mit einem Mutex absichert werden, kann dann fast nichts mehr passieren?
Gibt es Richtlinien für Thread-Safe-Programmierungen?
LG
Luisi
-
s.luis schrieb:
Okay, kann man dann sagen wenn die einzelnen Threads zum Beispiel nur read-Rechte haben, ist eine struct oder ein einfaches array thread-safe? Auch wenn einige 100 Threads darauf zugreifen?
Ja, nur parallele Reads auf ein Array sind thread-safe. Auch das lesen normaler Variabeln ist thread-safe (zumindest in den mir bekannten Sprachen).
Man kann aber leicht Datenstrukturen bauen, bei denen ein einfaches Read von aussen thread-safe aussieht, der Funktionsaufruf aber nicht thread-safe ist. Hier ein Beispiel:class Foo { private: int nof_reads; std::string data; public: std::string read_data() { ++nof_reads; // Race Condition return data; } // ... };
s.luis schrieb:
Wenn die Write-Rechte dann mit einem Mutex absichert werden, kann dann fast nichts mehr passieren?
Mutex ist kurz fuer "Mutual Exclusion", was uebersetzt "gegenseitiger Ausschluss" bedeutet. Das Mutex umschliesst eine Critical Section (CS) (das ist der Teil, indem es Fehler geben kann, wenn mehrere Threads gleichzeitig drin sind). Das Mutex sorgt dafuer, dass nur ein Thread gleichzeitig in die CS eintreten darf.
Hier ein C#-Beispiel:class Foo { int nof_reads; string data; object _mutex = new object(); public string read_data() { lock (_mutex) { ++nof_reads; // Das ist die CS. Hier kann nur ein Thread gleichzeitig eintreten } return data; } // ... }
s.luis schrieb:
Gibt es Richtlinien für Thread-Safe-Programmierungen?
Ja, von denen gibt es viele. Allgemein kann man sagen, das Parallele Programmierung ein sehr kompliziertes Gebiet ist. Es ist auch aktueller Forschungsgegenstand - es gibt sehr viele ungeloeste Probleme und man fuer vieles noch keine guten Loesungen gefunden.
-
Manchmal kann man sich Mutex, Semaphore etc. sparen, wenn man geschickt vorgeht.
Z. B.:
- Daten der Threads voneinander abkapseln.
- Globale Daten, die sich nach der Initialisierung nicht mehr ändern, müssen VOR der Threaderzeugung initialisiert werden.
- Daten geschickt aufteilen. Z. B. bei paralleler Matrizenberechnung, dass jeder Thread bestimmte Zeilen berechnet und auch wirklich nur diese.
-
icarus2 schrieb:
Allgemein kann man sagen, das Parallele Programmierung ein sehr kompliziertes Gebiet ist. Es ist auch aktueller Forschungsgegenstand - es gibt sehr viele ungeloeste Probleme
welche?
-
http_//www.c-plusplus.net/ schrieb:
icarus2 schrieb:
Allgemein kann man sagen, das Parallele Programmierung ein sehr kompliziertes Gebiet ist. Es ist auch aktueller Forschungsgegenstand - es gibt sehr viele ungeloeste Probleme
welche?
Eine effiziente Erkennung und Vermeidung von Deadlocks seitens des Betriebssystems. Es gibt den Bankieralgorithmus, aber hier müssen die Anzahl der Prozesse, sowie Ressourcen konstant sein und es muss vor Ausführung der Programme bekannt sein, welche Ressourcen sie benötigen. Sowas geht, nur bei statischen Betriebssystemen, wo es z. B. konstant 4 Tasks mit 8 Ressourcen gibt.
-
Steffo schrieb:
http_//www.c-plusplus.net/ schrieb:
icarus2 schrieb:
Allgemein kann man sagen, das Parallele Programmierung ein sehr kompliziertes Gebiet ist. Es ist auch aktueller Forschungsgegenstand - es gibt sehr viele ungeloeste Probleme
welche?
Eine effiziente Erkennung und Vermeidung von Deadlocks seitens des Betriebssystems. Es gibt den Bankieralgorithmus, aber hier müssen die Anzahl der Prozesse, sowie Ressourcen konstant sein und es muss vor Ausführung der Programme bekannt sein, welche Ressourcen sie benötigen. Sowas geht, nur bei statischen Betriebssystemen, wo es z. B. konstant 4 Tasks mit 8 Ressourcen gibt.
Ach sowas. Ich dachte es gibt was interessantes.
-
Jo, man merkt, dass du in einem anderem Umfeld tätig bist, wo ein Deadlock nicht viel ausmacht, weil man mal eben das Programm neustarten kann oder ggf. ein Patch nachliefert...
-
Steffo schrieb:
Jo, man merkt, dass du in einem anderem Umfeld tätig bist, wo ein Deadlock nicht viel ausmacht, weil man mal eben das Programm neustarten kann oder ggf. ein Patch nachliefert...
Bist du blind? Dein Bankieralgorithmus ist für ein klassisches Betriebssystem total unbedeuten, daher auch total interessant. Mehr hat der unregestierte nicht gesagt. Deine Assoziation ist auf jeden Fall voll daneben!
-
Tja, ich fand seinen Sarkasmus daneben.
-
Steffo schrieb:
Tja, ich fand seinen Sarkasmus daneben.
Bis auf dich, hat hier keiner Sarkasmus gezeigt, wenn's dir Problemfelder geht dann zeig sie auf, anstelle theoretische Lösung zu zeigen, die für die meisten Betriebssysteme keine Bedeutung hat.
-
Die meisten Betriebssysteme laufen nicht auf PC-Architektur. Der Bankieralgorithmus ist alles andere als reine Theorie und unbedeutend!
Das Problemfeld habe ich übrigens aufgezeigt, weil es keine effiziente Lösung für dynamische OS gibt!
-
Steffo schrieb:
Die meisten Betriebssysteme laufen nicht auf PC-Architektur. Der Bankieralgorithmus ist alles andere als reine Theorie und unbedeutend!
Das Problemfeld habe ich übrigens aufgezeigt, weil es keine effiziente Lösung für dynamische OS gibt!Sorry, wenn ich dir das sage, lern lessen.
Ich tendiere dazu, dass die meisten Betriebssysteme dynamisch sind - okey nicht wirklich gezählt, aber intuitive und tendenzielle. Lass mich mal beginnen mit dem Desktopbetriebsystemen: MacOSX (mein MacBook Pro), Windows(mein Rechner), Linux(meine VM), Android(mein Handy), Unix/Linux(mein Router) sind dynamisch. In meinen Umfeld haben ich potenzielle an statische Betriebssysteme: mein Waschmaschine, meine Offen, meine Mikrowelle, ob diese Geräte ein Betriebssystem haben? Meine Kaffemaschine, meine Mixer, meine Wage werden wohl keine Betriebssysteme haben, weil sie sind auch recht alt.
Außerdem wird in der Medizintechnik, in Telekommunikationtechnik, Radartechnik auf Echtzeitbetriebssysteme QNX gesetzt. QNX ist auch dynamisch. Oder andere Lösungen.
Verdachtweise laufen die meisten Unterhaltungsequipment linux-basiered oder proprietär, jedenfalls hab ich keins.Chipkarten können auch Betriebssystem haben, sind laut der Theorie keine nebenläufige System, weil sie wie Zustandmaschine ablaufen.
Wo verstecken sich deine statische Betriebssysteme? ^^
Theorie bilden das fundamentale Handeln eines Informatiker. Wenn du dich nicht mit der Theorie in deinem Anwendungsbereich kennst, dann solltest du kein Job dort anstreben. "Reine Theorie" sollten nicht von echten Informatiker in den Mund genommen werden.
-
Statische Betriebssysteme: Überall dort, wo sich die Ressourcenanzahl nicht ändert und das sind die meisten im embedded Bereich. In der Motorsteuerung z. B. - da werden statische Realzeitsysteme und Deadlockvermeidung verwendet (ob das der Bankieralgorithmus ist, weiß ich nicht, aber ich hatte erst vor wenigen Tagen ein Gespräch mit einem Automobilzulieferer...).
Über 90% der verkauften Computer sind embedded Systeme. Windows und Mac OS nehmen keinen großen Marktanteil ein. Linux ist für viele Microcontroller überladen. Sowas passt einfach nicht in Microcontroller mit 8 - 16 kb RAM rein!Das mit dem Lesen kann ich nur zurückgeben: Das Problem mit der effizienten Deadlock-Erkennung bleibt bei dyn. OS immernoch ungelöst. Wenn du anderer Ansicht bist, dann zeig mir mal ein OS das das kann!
-
-.-
-
- Sind die Steuerungsprogramme wirklich Betriebssysteme? Sorry ich vergaß, dass kannst du garnicht beurteilen.
Das sind statische Echt-Zeit-Betriebssysteme, die auch Deadlocks verhindern können. Das wurde mir so gesagt!
Weil du keine Lösung kennst, bedeutet nicht, dass es dafür keine Lösung existiert.
Schlage einfach mal OS-Literatur auf und informiere dich darüber, z. B. von Stallings "Operating Systems Internals and Design Principles". Außerdem habe ich von "keiner effizienten Lösung" gesprochen!
EDIT: Oh, du hast dein Beitrag gelöscht...