[C++] std::string en multi-threading

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Wat is nodig om een string veilig door te geven aan een andere thread? Moet je dan met c_str() forceren dat er geen 'reference' wordt gemaakt maar een echte kopie (afhankelijk van de implementatie van std::string)?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 11:21
Waarom zou je geen reference door willen geven? Hoe zie je dat 'doorgeven' ueberhaupt voor je?

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat doorgeven wilde ik doen in een critical section. Ik roep een function aan in thread A die in een CS de string in een list stopt. Dan lees ik in thread B die string uit de list (ook in een CS). Vervolgens wilde ik die string buiten een CS benaderen.
Maar als dat allemaal by-reference gebeurd kan het zijn dat thread A (die misschien ook nog iets met die string doet) en thread B 'in de knoop' raken.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

als je een reference doorgeeft moet je natuurlijk zorgen voor concurrency control, dus dat niet 2 threads tegelijk met 1 string bezig zijn

maar anders kun je natuurlijk gewoon prima een kopie meegeven door gewoon een nieuwe std::string te maken

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 11:21
Ah. Nou ja, .oisyn zegt eigenlijk alles al. In dit geval zou je gewoon in je critical section de string die je uit de lijst haalt kunnen kopiëren.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik was niet van plan een reference door te geven, maar wat nou als de std::string implementatie intern wel met een reference werkt?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 11:21
OlafvdSpek schreef op 15 oktober 2002 @ 14:56:
Ik was niet van plan een reference door te geven, maar wat nou als de std::string implementatie intern wel met een reference werkt?
Als dat zo is, zou dat ergens gespecificeerd moeten staan. Het lijkt me niet meer dan logisch dat wanneer je een std::string kopieert, de kopie verder onafhankelijk van het origineel is. Misschien zou het in verband met performance handig zijn om dit niet te doen, maar dat lijkt me sterk. In dat geval zou de std::string klasse in ieder geval thread-safe moeten zijn, zodat je er tenminste als gebruiker geen weet van hebt.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker: in de specificatie staat juist dat dat niet gespecificeerd is. Een implementatie mag zowel met references en copy-on-demand werken als gewoon direct kopieren :)

OlafvdSpek: met kopieren bedoel ik dan ook daadwerkelijk kopieren ipv met de copy-constructor een nieuwe string te maken, dus bijvoorbeeld met de iterators:
C++:
1
2
3
4
std::string copyString (const std::string & src)
{
    return std::string (src.begin (), src.end ());
}

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Soultaker schreef op 15 oktober 2002 @ 14:58:
Als dat zo is, zou dat ergens gespecificeerd moeten staan. Het lijkt me niet meer dan logisch dat wanneer je een std::string kopieert, de kopie verder onafhankelijk van het origineel is. Misschien zou het in verband met performance handig zijn om dit niet te doen, maar dat lijkt me sterk. In dat geval zou de std::string klasse in ieder geval thread-safe moeten zijn, zodat je er tenminste als gebruiker geen weet van hebt.
Nope, foute conclusie. Het staat niet in de specificaties, en daarom mag je er niet van uitgaan dat het gebeurt. Sterken nog, vele std::string implementaties zijn "copy-on-write" wat betekent dat de gecopieerde stringrepresentaties niet onafhankelijk van het origineel zijn, totdat je ze verandert middels een non-const methode. Simpel een copietje maken volstaat dus niet, het zou platfom-afhankelijke bugs kunnen introduceren.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 11:21
Verwijderd schreef op 15 oktober 2002 @ 15:17:
Nope, foute conclusie. Het staat niet in de specificaties, en daarom mag je er niet van uitgaan dat het gebeurt. Sterken nog, vele std::string implementaties zijn "copy-on-write" wat betekent dat de gecopieerde stringrepresentaties niet onafhankelijk van het origineel zijn, totdat je ze verandert middels een non-const methode. Simpel een copietje maken volstaat dus niet, het zou platfom-afhankelijke bugs kunnen introduceren.
Dat betekent dus dat in een multithreaded omgeving het copy-on-write deel van std::string onbruikbaar is (en je dus elke keer expliciet moet kopiëren). Zonde. Als je 't mij vraagt zou je die buffer net zo goed threadsafe kunnen maken - dat kost je waarschijnlijk niets.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op 15 oktober 2002 @ 16:30:
[...]

Dat betekent dus dat in een multithreaded omgeving het copy-on-write deel van std::string onbruikbaar is (en je dus elke keer expliciet moet kopiëren). Zonde. Als je 't mij vraagt zou je die buffer net zo goed threadsafe kunnen maken - dat kost je waarschijnlijk niets.


Even een implementatiedetail:
In de documentatie van VC7 staat dat de STL objecten niet thread-safe zijn, en ik weet dat ze ook niet met references werken.
Ik geloof (als in: heb er wel eens naar gekeken maar weet het niet meer zeker) dat VC6 wel met references werkte, en dat ze daar wel thread-safe waren (als je linkte met de multithreaded lib iig)

ik heb de documentatie van VC6 hier niet geinstalleerd dus ik zou het niet kunnen controleren (en gek genoeg kan ik de klasse basic_string ook niet vinden in de header files :?)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Hier is geen snel antwoord op. Het boek hierover is MXC++ (van Herb Sutter), maar die ligt op m'n werk.

Sowieso is multithreading implementation-specific. De VC6 std::string is zeker een COW string, threadsafe maar daardoor langzaam. COW kun je uitzetten. VC7 gebruikt geen COW, maar doet in plaats daarvan de small-string optimalisatie.

Threadsafety heeft altijd een prijs. De buffer moet uiteindelijk van de heap komen, en dat is een MT bottleneck. De small-string optimalisatie stelt het moment uit waarop je naar de heap moet; daardoor is het vooral in multi-threaded omgevingen zo effectief. Herb Sutter heeft de getallen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1