Threads Variablenübergabe



  • Hi ihr!

    Ich wollte mal einen Tipp von euch.

    Wenn ich einen Thread öffne, macht man das ja so:

    int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *),void *arg);

    An die Threads möchte ich Übertragungssockets (int c) übergeben, also das letzte Argument in pthread_create. Wenn ich mehrere Threads öffne, ihnen jeweils c übergebe und das Programm die Threads nicht so schnell kreiert, dann übernimmt er ja für mehrere Threads oft das letzte c, da sich c in der Zwischenzeit geändert haben kann.

    Wie geht ihr mit dem Problem um? Ein Abfangen des Problems mit phtread_join kommt nicht in Frage, da die Threads sonst zu lange das Programm unterbrechen würden. Die einzige Möglichkeit, die ich sehe ist, die Übertragungssockets in einer Liste anzulegen und einen Pointer auf das jeweilige Element der Liste anzugeben (übergeben kann man bei bei der Listenfunktion der Standard Template Library allerdings nur einen Iterator, der in der Zwischenzeit auf ein ganz anderes Element zeigen kann. Ein Array/Vektor hätte den Nachteil, dass sich die Inhalte verschieben würden, wenn zwischenzeitlich Elemente daraus gelöscht werden und die Übergabe somit nicht mehr eindeutig wäre).

    Gibt es nicht eine einfachere und trotzdem zuverlässige Möglichkeit, verschiedene int-Variablen eindeutig und sicher an Threads zu übergeben?

    Danke + viele Grüße, Marc



  • normalerweise löst man sowas auf eine andere art. du hast einen thread, der diese sockets erstellt. dieser fügt die sockets in eine liste ein und jeder thread, der grad nichts zu tun hat, holt sich den nächsten socket dort raus. damit das klappt, muss die liste für den gleichzeitigen zugriff geschützt werden. dafür gibt es funktionen mit prefix "pthread_cond_".
    es ist sinnvoller, eine gewisse menge an threads schon beim programmstart zu erzeugen. sollte man später weitere threads brauchen, kann ma diese immer noch zusätzlich erzeugen. sollten wiederum zu einem späteren zeitpunkt viele threads untätig herumwarten, kann man ein paar beenden.



  • Hi!

    Danke erstma für die Antwort! 🙂 Zu den Conditions habe ich noch eine Frage: Kann man, anders als bei Semaphoren, die systembedingt begrenzt sind und sonst zu viele Systemressourcen schlucken, beliebig viele, also tausende von Mutexen und Conditions gleichzeitig im Programm haben? Im Chatprogramm wäre es ja nachher überflüssig, alle Threads aufzuwecken, wenn Sätze nur für die Personen eines Raums oder für eine Einzelperson ausgegeben werden müssen. Ist es machbar und für den Prozessor verantwortbar, dass man also so viele Mutexe oder Conditions zu laufen hat, wie es Räume und User im Chat gibt?

    Die auszugebenden Chatzeilen sollen in einen Buffer der Einzelpersonen geschrieben werden. Wäre man für eine Person für jede Chatzeile jeweils einen anderen Thread benutzen, weiß man ja nicht, ob der vorige Thread, der die vorige Zeile ausgegeben hat, schon fertig ist und es könnten 2 Ausgaben gleichzeitig über einen Socket gesendet werden. Kann man von "außen" rausfinden, ob ein Thread gerade tätig ist oder schläft?

    Viele Grüße + Danke,
    Marc



  • Übergeb jedem Thread ein eigenes c:

    int * arg = new int(socket);

    und dann im thread:

    int * arg = (int 😉 param;
    int socket = *arg;
    delete arg;



  • Hi! Na wenn man z.B. eine Aufgabenliste anlegt, wo sich die Threads die einzelnen Aufgaben rausfischen (s. Beitrag darüber mit der Condition-Variable, was gut umsetzbar war), dann kann man ja in der Liste den Übertragungssocket mitübergeben (in einer Struktur). Meine Frage war mehr, ob man sinnvollerweise

    a) im Chat pro Client die neuen Chatzeilen in einen Buffer gibt und jeder Client einen eigenen Thread für das Auslesen und Ausgeben der Chatzeilen hat, der bei neuen Zeilen geweckt wird, der dann an den Client die neuen Chatzeilen sendet. Nachteil dieser Methode wäre, dass der Thread zweimal, nämlich am Anfang und am Ende der Übertragung den Cache des Benutzers prüfen muss (inklusive Sperren durch Mutex), da es ja sein kann, dass im Laufe der Übertragung eine neue auszugebende Zeile vorliegt.

    oder

    b) man pro neu eingegebener Chatzeile einen neuen Thread weckt, der aus der Liste eine Aufgabe (=auszugebende Zeile) rausfischt und die Zeile an den Client schickt. Die Frage hierbei ist, ob wenn ein anderer Thread mit der Übertragung der vorigen Zeilen länger braucht und gleichzeitig eine neue Zeile geschickt werden muss, man auf einem Übertragungssocket zwei Zeilen gleichzeitig sendet und der Browser dann Kauderwelsch ausgibt. Auch kann man ja nicht garantieren, dass die Zeilen dann in der richtigen Reihenfolge ausgegeben werden, da das Betriebssystem selbst bestimmt, in welcher Reihenfolge es die Threads bemüht.

    Liebe Grüße, Marc



  • Für einen IRC Client würde ich generell höchstens über einen GUI und einen Netzwerkthread nachdenken. Notfalls vielleicht noch ein Netzwerkthread pro Server. Aber keinen eigenen Thread pro Channel.



  • btw... ich weiß nicht, warum des alles Multithreaded sein soll, ich mein, eventuell ist des zu verstehen, wenn man GUI programmiert und so, aber im Allgmeinen kann man auch ein select() oder ein nicht blockierendes select(), das alle halbe sekunde mal aufgerufen wird, reinimplementieren, weiß nicht, wo da das Problem ist, finde in dem Fall so riesig viele Threads zu bauen kostet mehr (an Implementierungsarbeit), als es bringt. Man könnte das ganze allerdings auch über Pools erledigen, die Möglichkeit halte ich für sehr schön. Allerdings muss man halt auch alles wengl mischen, so nen Pool, ne Liste an Aufgaben (Nachrichten, etc),...


Log in to reply