C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Multithreading, STL und der Standard
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Ernst Murnleitner
Guest





PostPosted: Tue Sep 12, 2006 12:59 am    Post subject: Multithreading, STL und der Standard Reply with quote



Hallo,

Gibt es in einem zukünftigen C++ Standard irgendwelche Erweiterungen
oder Definitionen für Multithreading?

Ich habe mich in letzter Zeit in multithreading eingelesen. Im C++
Standard ist ja keinerlei Erwähnung von multithreading, zumindest was
die Container-Klassen betrifft. Ich verstehe auch, dass aus Performance
und Granularitäts-Gründen das Sperren bei gleichzetigem Zugriff
GÄNZLICH auf Userebene und nicht auf Bibliotheksebene erfolgen soll (im
Gegensatz zu Java?).

Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.

Dieses Ziel erscheint mir auch nicht sehr aufwendig zu erreichen sein.
Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?

Wenn sich die verrschiedenen Implementationen der STL so unterschiedlich
bzw. undefiniert verhalten, ist es schwer portable Programme zu
schreiben. So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads gleichzeitig
lesend zugegriffen werden kann. Wie schaut es aber aus, wenn man in
einer std::deque ein Element am Ende einfügt, dürfen dann die anderen
Threads am Anfang lesen? Ich denke, sowas inst gänzlich undefiniert und
ich müsste den Container bei JEDEM Schreibzugriff exklusiv sperren, um
kompatibel zu bleiben. Oder müsste man sogar beim alleinigen Lesen mit
mehrern Trhead den Container sperren?



Ernst
Back to top
Torsten Robitzki
Guest





PostPosted: Tue Sep 12, 2006 3:11 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote



Ernst Murnleitner wrote:

Quote:

Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.

Was für Operationen sollten das den sein? Ich würde immer erwarten, das
mehrere threads auf einen container zugreifen können, der seine Werte
nicht ändert. Der standard kennt im wesentlichen map, set, vector, list
und deque, keine diese Klassen haben ein Interface das sich anbietet um
auf durch verschiedene threads geänderte Daten zu zugreifen.

Quote:
Dieses Ziel erscheint mir auch nicht sehr aufwendig zu erreichen sein.
Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?

Was wären den Deine minmalen Anforderungen und wie wäre dann z.B.
std::list zu ändern?

Quote:
Wenn sich die verrschiedenen Implementationen der STL so unterschiedlich
bzw. undefiniert verhalten, ist es schwer portable Programme zu
schreiben. So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads gleichzeitig
lesend zugegriffen werden kann. Wie schaut es aber aus, wenn man in
einer std::deque ein Element am Ende einfügt, dürfen dann die anderen
Threads am Anfang lesen? Ich denke, sowas inst gänzlich undefiniert und
ich müsste den Container bei JEDEM Schreibzugriff exklusiv sperren, um
kompatibel zu bleiben. Oder müsste man sogar beim alleinigen Lesen mit
mehrern Trhead den Container sperren?

Man tut einfach gut daran, davon auszugehen, das auf eine Liste nicht
durch mehrere thread zugegriffen wird. Das sollte der default sein.
Warum alle Listen thread save machen, wenn nur auf einen Bruchteil
dieser von mehreren thread zugegriffen wird. Wenn ich eine Liste
zwischen mehreren thread teilen möchte, verwende ich eine Liste, die
dieses kann.

mfg Torsten
Back to top
Marcel Müller
Guest





PostPosted: Tue Sep 12, 2006 3:24 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote



Ernst Murnleitner wrote:
Quote:
Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.

Ja, aber mehr nicht. Dazu bedarf es überhaupt keiner Massnahmen.

Lesende Zugriffe verändern keinerlei Daten, also können zwei lesende
Zugriffe auch nicht interagieren.

Verschiedene Klasseninstanzen überlappen sich nicht im Speicher. Also
können sich Threads dabei auch nicht in die Quere kommen. Die Ausnahme
wären nichtkonstante, statische Datenelemente. Diese wiederum sind bei
den Container-Klassen wenig hilfreich, denn sie würden nicht nur
Interaktionen zwischen den Threads bewirken, sondern auch zwischen den
Instanzen in einem Thread.

Quote:
Wenn sich die verrschiedenen Implementationen der STL so unterschiedlich
bzw. undefiniert verhalten, ist es schwer portable Programme zu
schreiben. So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads gleichzeitig
lesend zugegriffen werden kann.

Ja. Das lässt sich gar nicht verhindern, dass das funktioniert.

Quote:
Wie schaut es aber aus, wenn man in
einer std::deque ein Element am Ende einfügt, dürfen dann die anderen
Threads am Anfang lesen?

Nein. Nicht im allgemeinen.

Allerdings bleiben Iteratoren gültig. Das gilt eigentlich unabhängig
davon, welchem Thread sie gerade gehören. (Obwohl ich mir theoretisch
Implementationen vorstellen kann, bei denen das in die Hose geht.)

Quote:
Ich denke, sowas inst gänzlich undefiniert und
ich müsste den Container bei JEDEM Schreibzugriff exklusiv sperren, um
kompatibel zu bleiben.

Jein, mit den Iteratoren geht da was.

Quote:
Oder müsste man sogar beim alleinigen Lesen mit
mehrern Trhead den Container sperren?

Nein.


Marcel
Back to top
Markus Schaaf
Guest





PostPosted: Tue Sep 12, 2006 4:35 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

"Ernst Murnleitner" <mur (AT) awite (DOT) de> schrieb:

Quote:
Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.

Beispiel?

Quote:
Dieses Ziel erscheint mir auch nicht sehr aufwendig zu erreichen sein.

Hmmm.

Quote:
Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?

Welche?

Quote:
Wenn sich die verrschiedenen Implementationen der STL so unterschiedlich
bzw. undefiniert verhalten, ist es schwer portable Programme zu
schreiben.

So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads gleichzeitig
lesend zugegriffen werden kann. Wie schaut es aber aus, wenn man in
einer std::deque ein Element am Ende einfügt, dürfen dann die anderen
Threads am Anfang lesen?

Ich denke, sowas inst gänzlich undefiniert und
ich müsste den Container bei JEDEM Schreibzugriff exklusiv sperren, um
kompatibel zu bleiben.

Das gilt sogar beim Schreiben in eine einzelne Variable, außer es
ist zufällig genau ein Maschinenwort. Ich kann da keine echte
Einschränkung erkennen.

Quote:
Oder müsste man sogar beim alleinigen Lesen mit
mehrern Trhead den Container sperren?

Das ist zwar implementation-defined, sollte sich jedoch für alle
gängigen Fälle mit "Nein." beantworten lassen.
Back to top
kanze
Guest





PostPosted: Tue Sep 12, 2006 3:20 pm    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Ernst Murnleitner wrote:

Quote:
Gibt es in einem zukünftigen C++ Standard irgendwelche
Erweiterungen oder Definitionen für Multithreading?

Wahrscheinlich. Es wird kräftig diskutiert, und von was ich
sehe, habe ich den Eindruck, dass es nicht nur einen Konsensus
dafür gibt, aber dass die meisten Leute halten es für eine der
wichtigsten Erweiterungen.

Quote:
Ich habe mich in letzter Zeit in multithreading eingelesen. Im
C++ Standard ist ja keinerlei Erwähnung von multithreading,
zumindest was die Container-Klassen betrifft.

Na, ja, da wahrscheinlich in aller ersten Linien, weil z.Z.
erkennt die Norm überhaupt keine Threads. Aber wo es um die
Container gibt, denke ich, dass sie sowieso mehr oder weniger
davon unbetroffen sind.

Quote:
Ich verstehe auch, dass aus Performance und
Granularitäts-Gründen das Sperren bei gleichzetigem Zugriff
GÄNZLICH auf Userebene und nicht auf Bibliotheksebene erfolgen
soll (im Gegensatz zu Java?).

Momentan sagt die Norm nicht. Höchst wahrscheinlich, denke ich,
wird, dass die zukunftige Norm die selben Garantien gibt, als
die SGI-Implementierung heute. (Da auch besteht m.E. ein
Consensus.)

Merk wohl auch, dass Java hat seine Meinung in dieser Hinsicht
geändert, und dass die neueren Java-Collections auch ehe die
SGI-Garantien geben, und nicht mehr.

Quote:
Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht
genommen, dass mehrer Threads gleichzeitig aus einem Container
lesen bzw. mehre Threads in verschiedene Container schreiben
können.

Die SGI-Garantien entsprechen ungefähr, was Posix für die
Grundtypen garantiert. Solange nur gelesen wird, ist keine
besondere Vorschrift zu beachten. Sofort geschreiben wird, aber,
müssen alle Zugriffe vom Benutzer geschützt werden.

Quote:
Dieses Ziel erscheint mir auch nicht sehr aufwendig zu
erreichen sein. Sollte man daher nicht minimale Anforderungen
in den Standard aufnehmen?

Wird sicher getan, sofort die Norm überhaupt Threads erkannt.
(Merk wohl, es fängt schon bei int an. Darf mehrere Threads ein
int lesen? Schreiben? Unter welchen Bedingungen?)

Quote:
Wenn sich die verrschiedenen Implementationen der STL so
unterschiedlich bzw. undefiniert verhalten, ist es schwer
portable Programme zu schreiben.

Was hast du für Unterschiede gesehen. Die Implementierungen von
g++ und von VC++ verhalten sich ähnlich, so weit ich weiß --
wie die von SGI und von STLport. In der Tat habe ich nur die
Implementierung von Sun gesehen, die sich anders verhält (und
Sun scheint davon zurückzutreten), wenn du aber die SGI-Regeln
anhalten, geht's auch da.

Quote:
So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads
gleichzeitig lesend zugegriffen werden kann.

Bei der STL streng genommen. Es gibt eine ganz kleine Ausnahme
bei std::basic_string in G++. In bestimmten Fällen da brauchst
du wohl ein Lock, auch wenn du nur liest. (Wenn man das Problem
kennt, ist aber leicht umzugehen.)

Quote:
Wie schaut es aber aus, wenn man in einer std::deque ein
Element am Ende einfügt, dürfen dann die anderen Threads am
Anfang lesen?

Freilich. Unter der selbständigen Bedingung, dass alle Threads
die richtige Synchronisierung gemacht habe.

Quote:
Ich denke, sowas inst gänzlich undefiniert und ich müsste den
Container bei JEDEM Schreibzugriff exklusiv sperren, um
kompatibel zu bleiben.

Alle Zugriffe müssen gesperrt sein, sofort ein einziger Thread
was ändert. Technisch geht es sogar nicht anders.

Quote:
Oder müsste man sogar beim alleinigen Lesen mit mehrern Trhead
den Container sperren?

Solange nur gelesen wird, brauchst du keines besonders zu tun.
Außer bei std::basic_string in G++ (und dann nur in
Sonderfällen).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
kanze
Guest





PostPosted: Tue Sep 12, 2006 4:27 pm    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Marcel Müller wrote:
Quote:
Ernst Murnleitner wrote:
Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht
genommen, dass mehrer Threads gleichzeitig aus einem
Container lesen bzw. mehre Threads in verschiedene Container
schreiben können.

Ja, aber mehr nicht. Dazu bedarf es überhaupt keiner
Massnahmen.

Lesende Zugriffe verändern keinerlei Daten, also können zwei
lesende Zugriffe auch nicht interagieren.

Vorsicht. Du weißt nicht unbedingt, was sich hinter den Kulissen
stattfindet. Wenn ich einen std::string bei g++ kopiere, z.B.,
wird auch Teile des kopierten Objekts geändert.

Quote:
Verschiedene Klasseninstanzen überlappen sich nicht im
Speicher. Also können sich Threads dabei auch nicht in die
Quere kommen. Die Ausnahme wären nichtkonstante, statische
Datenelemente. Diese wiederum sind bei den Container-Klassen
wenig hilfreich, denn sie würden nicht nur Interaktionen
zwischen den Threads bewirken, sondern auch zwischen den
Instanzen in einem Thread.

Wenn sich die verrschiedenen Implementationen der STL so
unterschiedlich bzw. undefiniert verhalten, ist es schwer
portable Programme zu schreiben. So kann man wohl davon
ausgehen, dass bei den meisten Implementationen (oder bei
allen?) von mehreren Threads gleichzeitig lesend zugegriffen
werden kann.

Ja. Das lässt sich gar nicht verhindern, dass das funktioniert.

Doch. Schon bei std::string unter g++, in bestimmten Fällen.

Quote:
Wie schaut es aber aus, wenn man in einer std::deque ein
Element am Ende einfügt, dürfen dann die anderen Threads am
Anfang lesen?

Nein. Nicht im allgemeinen.

Allerdings bleiben Iteratoren gültig. Das gilt eigentlich
unabhängig davon, welchem Thread sie gerade gehören. (Obwohl
ich mir theoretisch Implementationen vorstellen kann, bei
denen das in die Hose geht.)

Aber... Nichts sagt, dass einen Iterator nicht Anteile des
Containers benutzt. Das heißt, dass grundsetzlich müssen auch
gesperrt werden, wenn ich Iteratoren habe, die einem Container
gehören, der geändert wird. Auch wenn die Änderung den Iterator
noch gültig lässt.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Marcel Müller
Guest





PostPosted: Wed Sep 13, 2006 12:44 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

kanze wrote:
Quote:
Lesende Zugriffe verändern keinerlei Daten, also können zwei
lesende Zugriffe auch nicht interagieren.

Vorsicht. Du weißt nicht unbedingt, was sich hinter den Kulissen
stattfindet. Wenn ich einen std::string bei g++ kopiere, z.B.,
wird auch Teile des kopierten Objekts geändert.

Das ist dann aber auch schon ein böser Hack, schließlich ist das
kopierte Objekt im allgemeinen konstant. Ok, mit mutable kann man sich
drücken. Aber es wäre zumindest einigermaßen dumm, wenn man solche Haken
und Ösen implementiert, nicht wenigstens da an Threads zu denken. Ich
bin eigentlich überzeugt davon, dass g++ da nicht patzt.

Quote:
Allerdings bleiben Iteratoren gültig. Das gilt eigentlich
unabhängig davon, welchem Thread sie gerade gehören. (Obwohl
ich mir theoretisch Implementationen vorstellen kann, bei
denen das in die Hose geht.)

Aber... Nichts sagt, dass einen Iterator nicht Anteile des
Containers benutzt. Das heißt, dass grundsetzlich müssen auch
gesperrt werden, wenn ich Iteratoren habe, die einem Container
gehören, der geändert wird. Auch wenn die Änderung den Iterator
noch gültig lässt.

Es wäre denkbar, dass ein Iterator es nach Rückkehr einer
modifizierenden Funktion wieder gültig ist und zwischendurch ungültig war.
Guten Programmierstil wollte ich das jetzt aber nicht nennen.

Ich muss auch sagen, dass ich bisher nicht in die Versuchung geraten
bin, auf solche Annahmen zu bauen, obwohl ich viel mit Threads arbeite.

Die klassischen Erzeuger-Verbraucher-Probleme (Queue/Stack/Ringpuffer)
löse ich üblicherweise mit effektiv 4 Element-Stati: leer/nicht
vorhanden, put pending, voll und get pending. Dadurch kommt man mit
einem Mutex für die ganze Liste aus, das immer nur für sehr kurze Zeit
gesperrt wird, und vermeidet jegliche weiteren Probleme.


Marcel
Back to top
Ernst Murnleitner
Guest





PostPosted: Wed Sep 13, 2006 2:45 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Markus Schaaf schrieb:
Quote:
"Ernst Murnleitner" <mur (AT) awite (DOT) de> schrieb:


Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.


Beispiel?


Die Doku zu gcc >= 3 zitiert die Doku zur SGI STL, die anscheinend die
Grundlage für die gcc-c++-stdlib ist. Dort gibt es ein FAQ zu threads wo
obiges garantiert wird.

http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#3


Quote:

Dieses Ziel erscheint mir auch nicht sehr aufwendig zu erreichen sein.


Hmmm.

Ich denke mir, wenn man darauf achtet, dass man bei den Leseoperationen
keine Membervariablen verändert werden, ist das meiste erledigt. Und
generell keine statischen Member. Aber ist nur ein Vermutung.


Quote:


Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?


Welche?


Die oben zitierten, die scheinen meist eh schon verwirklicht worden zu sein:

dass
Quote:
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.



Quote:
Das gilt sogar beim Schreiben in eine einzelne Variable, außer es
ist zufällig genau ein Maschinenwort. Ich kann da keine echte
Einschränkung erkennen.

Wenn nur aus dem Container gelesen wird, wären ja prinzipiell keine
Probleme zu erwarten. Wenn dann aber z.B. eine Member-Variable im
Container auf den aktuellen Datensatz zeigt, funktioniert es doch wieder
nicht...


Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Wed Sep 13, 2006 2:55 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Marcel Müller schrieb:
Quote:
Ernst Murnleitner wrote:

Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen,
dass mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre
Threads in verschiedene Container schreiben können.


Ja, aber mehr nicht. Dazu bedarf es überhaupt keiner Massnahmen.

Lesende Zugriffe verändern keinerlei Daten, also können zwei lesende
Zugriffe auch nicht interagieren.

Das war genau meine Frage. Ändern lesende Zugriffe wirklich keine Daten?
Wer sagt das? Wenn ich zum Beispiel eine Funktion GetNext...
programmieren würde, dann würde ich im Falle von multithreading die
vorige Position als Referenz übergeben, ohne multithreading würde ich
einfach eine Member-Variable BESCHREIBEN.


Quote:

Verschiedene Klasseninstanzen überlappen sich nicht im Speicher. Also
können sich Threads dabei auch nicht in die Quere kommen. Die Ausnahme
wären nichtkonstante, statische Datenelemente.

Oder zum Beispiel Debug-Ausgaben:

std::cerr << ...;

Wenn ich mehere Threads in std::cerr oder std::cout schreiben lasse,
kann ich regelmaessig Abstüzre produzieren.

Diese wiederum sind bei
Quote:
den Container-Klassen wenig hilfreich, denn sie würden nicht nur
Interaktionen zwischen den Threads bewirken, sondern auch zwischen den
Instanzen in einem Thread.

Ok, das betrift aber nur die Forderung vom Beschreiben verschiedener
Container gleichzeitig. Dann haben wir ja noch das Problem, ob aus einem
Container mehrfach gleichzeitig gelesen werden kann/sollte. Siehe oben.




Quote:

Wie schaut es aber aus, wenn man in einer std::deque ein Element am
Ende einfügt, dürfen dann die anderen Threads am Anfang lesen?


Nein. Nicht im allgemeinen.

Allerdings bleiben Iteratoren gültig. Das gilt eigentlich unabhängig
davon, welchem Thread sie gerade gehören. (Obwohl ich mir theoretisch
Implementationen vorstellen kann, bei denen das in die Hose geht.)

Bleiben die wirklich gültig? Bei std::list glaube ich ja, aber bei
std::vector auch?

Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Wed Sep 13, 2006 3:07 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Marcel Müller schrieb:
Quote:
kanze wrote:

Lesende Zugriffe verändern keinerlei Daten, also können zwei
lesende Zugriffe auch nicht interagieren.


Vorsicht. Du weißt nicht unbedingt, was sich hinter den Kulissen
stattfindet. Wenn ich einen std::string bei g++ kopiere, z.B.,
wird auch Teile des kopierten Objekts geändert.


Das ist dann aber auch schon ein böser Hack, schließlich ist das
kopierte Objekt im allgemeinen konstant. Ok, mit mutable kann man sich
drücken. Aber es wäre zumindest einigermaßen dumm, wenn man solche Haken
und Ösen implementiert, nicht wenigstens da an Threads zu denken. Ich
bin eigentlich überzeugt davon, dass g++ da nicht patzt.

Wäre das jetzt nicht genau der Fall, wo const-Funktionen gebraucht
sinnvol sind?

Zum Beispiel entnehme ich dem Stroustroup:

.... class vector {
....
size_type size() const;
....
iterator begin();
....
}


D.h. bei der Abfrage der Groesse wird - wer hätte sich das nicht gedacht
- der Container sicher nicht geändert. Bei begin() gilt diese Garantie
offensichtlich nicht.



Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Wed Sep 13, 2006 3:14 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Torsten Robitzki schrieb:
Quote:
Ernst Murnleitner wrote:


Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen,
dass mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre
Threads in verschiedene Container schreiben können.


Was für Operationen sollten das den sein? Ich würde immer erwarten, das
mehrere threads auf einen container zugreifen können, der seine Werte
nicht ändert. Der standard kennt im wesentlichen map, set, vector, list
und deque, keine diese Klassen haben ein Interface das sich anbietet um
auf durch verschiedene threads geänderte Daten zu zugreifen.

Siehe dazu auch meine Antwort in dem anderen Diskussionsbeitrag. Bei der
STL fällt mir jetzt auch keine Möglichkeit ein. Aber ich hatte bei
meiner Archiv-Klasse Funktionen wie GetFirstDataset und GetNextDataset
programmiert, wobei die erste eine interne Zählervariable bzw. iterator
auf den Anfang gesetzt hatte und die andere Funktion diese erhöht hatte.
Bei Multithreading war aber Schluss damit, da musste ich die Position
beim Funktionsaufruf übergeben.

Quote:
Dieses Ziel erscheint mir auch nicht sehr aufwendig zu erreichen sein.
Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?


Was wären den Deine minmalen Anforderungen und wie wäre dann z.B.
std::list zu ändern?

Nicht zu ändern (gleichzeitig lesen), sondern nur als Minimalanforderung
festlegen.


Quote:
Man tut einfach gut daran, davon auszugehen, das auf eine Liste nicht
durch mehrere thread zugegriffen wird. Das sollte der default sein.
Warum alle Listen thread save machen, wenn nur auf einen Bruchteil
dieser von mehreren thread zugegriffen wird. Wenn ich eine Liste
zwischen mehreren thread teilen möchte, verwende ich eine Liste, die
dieses kann.

Das finde ich wären auch sinnvolle ZUSÄTZLICHE Bibliotheken. Sehr oft
kommt es ja nicht so auf Geschwindigkeit an.


Ernst
Back to top
Markus Schaaf
Guest





PostPosted: Wed Sep 13, 2006 3:20 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

"Ernst Murnleitner" <mur (AT) awite (DOT) de> schrieb:

Quote:
Soweit ich aber verstanden habe, wird in der Praxis bei den
verschiedenen STL-Implementationen doch darauf rücksicht genommen, dass
mehrer Threads gleichzeitig aus einem Container lesen bzw. mehre Threads
in verschiedene Container schreiben können.

Die Doku zu gcc >= 3 zitiert die Doku zur SGI STL, die anscheinend die
Grundlage für die gcc-c++-stdlib ist. Dort gibt es ein FAQ zu threads wo
obiges garantiert wird.

http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#3

"Bei den verschiedenen" klingt nach "im Prinzip alle", nicht wahr?

Quote:
Sollte man daher nicht minimale Anforderungen in den Standard aufnehmen?

Die oben zitierten,

Unterschreib.
Back to top
Ernst Murnleitner
Guest





PostPosted: Wed Sep 13, 2006 3:23 am    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Hallo,

Quote:
Wenn sich die verrschiedenen Implementationen der STL so
unterschiedlich bzw. undefiniert verhalten, ist es schwer
portable Programme zu schreiben.


Was hast du für Unterschiede gesehen. Die Implementierungen von
g++ und von VC++ verhalten sich ähnlich, so weit ich weiß --
wie die von SGI und von STLport. In der Tat habe ich nur die
Implementierung von Sun gesehen, die sich anders verhält (und
Sun scheint davon zurückzutreten), wenn du aber die SGI-Regeln
anhalten, geht's auch da.


Habe ich keine gesehen, aber jemand meinte in dieser Gruppe, man kann
sich eben auf nichts verlassen, da multithreading nicht mal im Standard
erwähnt wird.


Quote:
So kann man wohl davon ausgehen, dass bei den meisten
Implementationen (oder bei allen?) von mehreren Threads
gleichzeitig lesend zugegriffen werden kann.


Bei der STL streng genommen. Es gibt eine ganz kleine Ausnahme
bei std::basic_string in G++. In bestimmten Fällen da brauchst
du wohl ein Lock, auch wenn du nur liest. (Wenn man das Problem
kennt, ist aber leicht umzugehen.)

Hast Du hier nähere Info? Ich hoffe, das ist wirklich ein Sonderfall.
Hat es eventuell mit c_str() zu tun?


Ernst
Back to top
Raymond Haeb
Guest





PostPosted: Wed Sep 13, 2006 3:55 pm    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Ernst Murnleitner wrote:
Quote:
Zum Beispiel entnehme ich dem Stroustroup:

Das ist ja auch nur ein einfaches Beispiel. In std::vector findet man auch:

Quote:

... class vector {
...
size_type size() const;
...
iterator begin();
...
const_iterator begin() const;


Quote:
}

D.h. bei der Abfrage der Groesse wird - wer hätte sich das nicht gedacht
- der Container sicher nicht geändert. Bei begin() gilt diese Garantie
offensichtlich nicht.

Dein begin liefert auch einen iterator zurück mit dem sich der Container
verändern läßt, das darf nicht const sein.


Raymond
Back to top
kanze
Guest





PostPosted: Wed Sep 13, 2006 5:18 pm    Post subject: Re: Multithreading, STL und der Standard Reply with quote

Marcel Müller wrote:
Quote:
kanze wrote:
Lesende Zugriffe verändern keinerlei Daten, also können zwei
lesende Zugriffe auch nicht interagieren.

Vorsicht. Du weißt nicht unbedingt, was sich hinter den
Kulissen stattfindet. Wenn ich einen std::string bei g++
kopiere, z.B., wird auch Teile des kopierten Objekts
geändert.

Das ist dann aber auch schon ein böser Hack, schließlich ist
das kopierte Objekt im allgemeinen konstant.

Was heißt aber konstant. Das sein Wert sich nicht ändert, oder.
(Ich gehe davon aus, dass die meisten Leute heute benutzen
logisches const, und nicht bitweise. Nicht dass das hier
irgendwas ändert.)

Das Problem, das wir hier haben, ist, dass die Schreibzugriffe,
am Sinn von Threading, alle Schreibzugriffe einschließen. Auch
diejenigen, die den logischen Zustand des Objektes nicht
verändern (falls man an logische Const denkt), und auch
diejenige an logischen Anteile des Objektes, die nicht direkt
innerhalb des Objekts legen (falls man an den von Compiler
benutzen bitweise Const denkt).

Quote:
Ok, mit mutable kann man sich drücken. Aber es wäre zumindest
einigermaßen dumm, wenn man solche Haken und Ösen
implementiert, nicht wenigstens da an Threads zu denken. Ich
bin eigentlich überzeugt davon, dass g++ da nicht patzt.

Bei std::basic_string benutzt man COW. Das heißt, dass beim
Kopieren eines Strings nur einen Referenzzähler inkrementiert
wird, und erst beim potenziellen Schreiben kopiert wird. Und
darin liegt das Problem: das String-Objekt kann nicht 100%
wissen, wenn geschrieben wird, und muss intern die Kopie machen,
auch wenn du nichts änderst (also z.B. beim Aufruf von
operator[] oder begin()). Wenn du nicht gesperrt hast, weil DU
weißt, dass keine das Objekt änderst. Und wenn kopiert wird,
ändert sich wohl Anteile der internen Darstellung des Objektes.

Dazu hat der Autor des std::string bei g++ gewollt, nicht zu
langsam zu sein; endlich geht's wohl, wenn man stetts innerhalb
des Objektes sperrt, nur wird's sehr langsam. Dazu benutzen sie
einige atomären Operationen. Leiter reichts in einigen
bestimmten Fällen nicht aus; in der Tat bin ich ehe überzogen,
dass die Schnittstelle zum std::string keine lockfreie COW erlaubt
(wobei mit einer sinnvolleren Schnittstelle wäre es möglich, und
vielleicht sogar sinnvoll).

Immerhin ist es, dass wenn 1) du einen nicht-const std::string
Objekt hast (vielleicht weil du es in main vor Anfang des
Threading mit einem Wert aus der Kommandozeile bzw. einer
Konfigurierungsdatei schreibst), 2) in einem Thread mit [],
at(), begin() oder end() angreifst, 3) in einem anderen Thread
gleichzeitig kopierst (also, dieses Objekt als Parameter des
Kopie-Constructors benutzt), und 4) es ist in beidem Fall die
erste solche Benutzung (also, es gibt keine andere Kopie der
Kette, und du hast nie vorher [], at(), begin() oder end()
darauf benutzt); dann (und nur dann) je nach dem genauen Ablauf,
kann es vorkommen, dass du nachher ein std::string Objekt hast,
dessen Speicher schon befreit worden ist.

Quote:
Allerdings bleiben Iteratoren gültig. Das gilt eigentlich
unabhängig davon, welchem Thread sie gerade gehören.
(Obwohl ich mir theoretisch Implementationen vorstellen
kann, bei denen das in die Hose geht.)

Aber... Nichts sagt, dass einen Iterator nicht Anteile des
Containers benutzt. Das heißt, dass grundsetzlich müssen
auch gesperrt werden, wenn ich Iteratoren habe, die einem
Container gehören, der geändert wird. Auch wenn die Änderung
den Iterator noch gültig lässt.

Es wäre denkbar, dass ein Iterator es nach Rückkehr einer
modifizierenden Funktion wieder gültig ist und zwischendurch
ungültig war. Guten Programmierstil wollte ich das jetzt aber
nicht nennen.

So geht es aber mit der STL. Unvermeidlich, fast.

Bei std::string ist es noch schlimmer. Du brauchst nicht, die
Kette zu ändern, um einen Iterator ungültig zu machen. Zum
Beispiel:

std::string a( "abc" ) ;
std::string b ;
std::string::iterator i = a.begin() ;
char c = a[ 0 ] ;
// Und hier ist i ungültig. Laut der Norm, und
// in der Tat mit g++ und Sun CC... und ältere
// Versionen VC++.

Quote:
Ich muss auch sagen, dass ich bisher nicht in die Versuchung
geraten bin, auf solche Annahmen zu bauen, obwohl ich viel mit
Threads arbeite.

Auf welchen Annahmen? Iteratoren sind äußerst gefährlich, auch
ohne Threads. Du musst ganz genau wissen, was du tust. In
Allgemein gilt es, du kannst sie als Parameter eines standard
Algorithmus benutzen, oder in deinen eigenen kleinen Schleifern;
du sollst aber nie versuchen, sie länger zu behalten.

Quote:
Die klassischen Erzeuger-Verbraucher-Probleme
(Queue/Stack/Ringpuffer) löse ich üblicherweise mit effektiv 4
Element-Stati: leer/nicht vorhanden, put pending, voll und get
pending. Dadurch kommt man mit einem Mutex für die ganze Liste
aus, das immer nur für sehr kurze Zeit gesperrt wird, und
vermeidet jegliche weiteren Probleme.

Das ist eigentlich ein sehr nutbarer Vorgang. Ich tue es auch
so; dazu benutze ich std::auto_ptr an der Schnittstelle der
Queue, damit ich sicher bin, dass der Sender nicht weiter mit
dem Objekt umgeht. Dass verhindert freilich aber nicht alle
Probleme; hast du einen Zeiger im übergegebenen Objekt, zum
Beispiel...

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.