richtiges Multithreading
-
Hallo,
ich habe momentan ein Programm, das zunächst auf eingehende Verbindungen wartet und wenn sich ein neuer Client verbindet muss dieser individuell behandelt werden, je nachdem was er an den Server schickt. Und das mit bis zu mehren hundert Clients gleichzeitig.
Ich hatte mir geadacht das mit Threads zu lösen, also pro Client ein Thread.
Nur habe ich folgende Probleme:a) dadurch, dass ich in dem Thread eine Methode innerhalb der gleichen Klasse aufrufen muss, kann ich dieser Methode keinen Wert mehr übergeben (oder?)
b) nun könnte ich das o.g. Problem dadurch lösen, den jeweiligen Wert temporär in einer globalen Variable zu speichern, das ist aber schlechter Stil (oder?)
c) wie verwalte ich die Threads am besten, wie speichere ich die Thread-Handles?
In Vektoren? Wenn ein Thread zu Ende ist und irgendwann mal mehrere gleichzeitig auf den Vektor zugreifen stürzt doch das Program ab, oder?Wie ihr sehen könnt bin ich ein wenig ratlos wie ich das gut implementiere.
Und Bibliotheken wie boost kommen für mich nicht in Frage.
-
Hi,
also ich würde mir an Deiner Stelle Mal mehr Zeug zu Synchronisation durchlesen.
Wenn Du gemeinsam genutzte Ressourcen über Threads manipulierst, solltest Du die entsprechend schützen, beispielsweise durch Mutexe (dazu findest Du in der Threading-Bibliothek Deiner Wahl schon Mal etwas). Wenn eine Variable nur gelesen wird, kann der Zugriff hier auch von mehreren Threads beliebig geschehen. Schreibend ist es oft sinnvoll so einen Mutex drum herum zu setzen, sodass bei einem Schreiberling die anderen brav warten. a) geht also mit Einschränkungen.
Wie b) dein Problem lösen soll, verstehe ich nicht.
Verwaltung von Threads geht halt über einen Threadpool. Leider habe ich keine Best Practice auf Lager, aber die Handles können einen recht weiten Gestaltungsspielraum haben, je nachdem, was Du möchtest.
Welche Bibliothek willst Du nutzen, wenn nicht boost? Ohne Bibliothek wird das mit dem Multithreading nämlich schwierig.

-
Ok, wenn du das sagst, dass es sinnvoll ist eine Biblitohek zu verwenden werde ich mir boost mal anschauen.

Gibt es in der Hinsicht besondere Dinge zu beachten?Für weitere Tipps bin ich weiterhin dankbar.
-
Also ich würde mir bei Multithreading auch umfangreiche Tutorials ansehen, welche Arten von Synchronisation man mit Mutexen erstellen kann z.B. Es gibt bei Multithreading viel mehr zu beachten als man vorher überhaupt weiß. Ich habe jahrelang dies und das programmiert, nie jedoch Multithreading eingesetzt. Als ich dann das erste Mal damit in Berührung kam, habe ich gemerkt, dass dort ein vollkommen anderes Denken erfordert ist.
Ich würde also nicht einfach nur eine Klasse A und eine Klasse B aus boost::thread herausgreifen, sondern definitiv versuchen das Gesamtkonzept zu verstehen. Das erspart Dir nachher viel Ärger.
Ansonsten haben die anderen hier deutlich mehr Erfahrung mit Multithreading und Threadpools, vielleicht hat ja jemand auch besonders gute Links.

-
Sonst keiner Tipps?
Ungeachtet von boost jetzt mal: wie kann ich denn überhaupt einer mit CreateThread() aufgerufenen Funktion innerhalb der gleichen Klasse irgendwelche Daten übergeben?
-
Funktionen die einen Thread erzeugen bieten dir immer irgendwas wo du dem Thread Informationen mitgeben kannst. Meist ist es ein void-Zeiger.
Den kannst du dann entweder verwenden um z.B. einen einzelnen Zeiger zu übergeben (z.B. this-Zeiger).Oder du machst eine kleine struct wo du alle zu übergebenden Informationen reinpackst, legst davon eine Instanz mit new() an, und übergibst den Zeiger auf die Struct in dem void-Zeiger.
Wenn beim Anlegen des Threads ein Fehler passiert ist, dann musst du die struct wieder löschen. Und wenn das Anlegen des Threads funktioniert hat, dann muss dieser sofort Besitz an dem übergebenen Zeiger nehmen, d.h. ihn sofort z.B. in einen unique_ptr/scoped_ptr/... stecken, damit das Objekt auf jeden Fall gelöscht wird wenn der Thread terminiert.
Damit kannst du dann beliebig viele Informationen (Parameter) an den Thread übergeben.
boost::thread bzw. std::thread machen genau das für dich im Hintergrund, d.h. da musst du dich nicht mehr darum kümmern wie das mit der Parameterübergabe nun gemacht wird. Du übergibst einfach einen Funktor in den sämtliche Parameter schon reingebunden sind (z.B. mit boost::bind/std::bind), und den Rest erledigt die Library für dich.
-
Super Antwort, genau das wollte ich wissen!
Wollte mir gerade mal std::thread anschauen musste aber bemerken, dass ich die Headerdatei davon gar nicht standardmäßig habe und wenn ich google dann finde ich nur eine kostenflichtige Bibliothek.Kann mir da jmd. mal nen Link zu geben?
-
Benutze VS 2012 fuer Windows!
-
@nuffe:
std::thread ist noch relativ neu.
VisualStudio 2012 hat es dabei, aktuelle GCC Distributionen vermutlich auch.Du kannst aber auch einfach boost::thread verwenden.