map mit 3 werten



  • Hi zusammen,
    folgendes Verständnisproblem bzw auf Hilfe bin ich angewiesen. Ich habe mehrere Threads am Laufen, die nach ihrer Ausführung schlafen gelegt werden. Diese Threads erstellen Daten, die erst nach den Schlafen gültig sein sollen. Diese Daten sollen anschließend von einem "Hauptthread" gelesen über Socket versendet werden. Anschließend soll der "Hauptthread" schlafen und zur nächsten Laufzeit aufwachen.Da alles zeitlich begrenzt ist, weiss ich nicht so Recht wie ich das machen soll.

    Ich könnte eine map verwenden, aber wenn ein Thread kommt Daten bspw. Key 3 = value 4 ablegt das erst in 3s gütig sein soll. So kann ein anderer Thread diese Daten überschreiben. Habt die irgendwelche Ideen wie man dies noch lösen könnte?

    Ich hoffe die Situation einigermassen verständlich erzählt habe.



  • Sorry für den Titel. Habe es vergessen zu ändern :S



  • 😕
    Da hab ich ziemlich sicher was falsch verstanden:
    Du willst Threads parallel eine Map füllen lassen, aufgrund von Puffer-überläufen o.ä. aber mit 3s Verzögerung ?



  • Nein du hast es richtig verstanden. Ich möchte Threads parallel laufen lassen sie dein eine gewisse Zeit sagen wir mal 3s schlafen legen und nach dieser Zeit sollen sie ihre vorher berechneten Werte in eine gemeinsame map schreiben.



  • Verfolger schrieb:

    Ich möchte Threads parallel laufen lassen sie dein eine gewisse Zeit sagen wir mal 3s schlafen legen und nach dieser Zeit sollen sie ihre vorher berechneten Werte in eine gemeinsame map schreiben.

    Wo genau liegt das Problem ?
    Das die sich dann gegenseitig die Werte überschreiben?
    Dann könntest du auch eine Multimap nehmen, oder vorher regeln das nicht dieselben Schlüssel verwendet werden.



  • Das Problem liegt daran das die Daten die geschrieben werden erst ab dem Zeitpunkt des wiederaufwachens gültig sein sollen.

    Ein Bsp: T1 möchte bei Key 1 Value 5 nach 3s haben
    T2 möchte bei Key 1 Value 6 nach 5s haben
    Logisch wäre es wenn bei 3s der Wert 5 und nach 5s der wert 6 stehen würde.

    Ich möchte hiermit eine Vorhersage machen können, das dann vom Hauptthread gesteuert wird.

    Multimap muss ich mir mal anschauen. habe damit nicht soviele Erfahrungen.

    Danke dir für deine Bemühungen!



  • Nein, nein stopp. Dann hab ich's Problem falsch verstanden.
    In diesem Fall, mach das doch gleich mit nem art Puffer, also speicher die Daten irgendwo ab und nach 3 Sekunden kopier sie in die Map.



  • Ich habe mehrere Threads am Laufen, die nach ihrer Ausführung schlafen gelegt werden. Diese Threads erstellen Daten, die erst nach den Schlafen gültig sein sollen.

    Warum?

    while ...
      start 1 to n  thread
      wait for 1 to n threads (join)
      wait (3s)
      read and send data
    


  • Wie mache ich das am besten mit einem Puffer? ich habe mir eine Liste überlegt in der die Daten inklusive die Zeit als String abgespeichert wird und anschließend dann im Hauptthread auslesen und Zeiten vergleichen. Aber mit einer Liste ist es ein wenig ineffiziet.

    Hast vielleicht einen beseren Lösungsvorschlag?



  • Warum legst du Threads überhaupt schlafen? Das ist doch eher ein Hinweis auf schlechtes Design.



  • Verfolger schrieb:

    Hast vielleicht einen beseren Lösungsvorschlag?

    Wieso ?
    Die Idee mit der Liste geht ja schon (kannst es ja noch ausweiten, um es 'effizienter' zu machen).
    Du verwaltest diese also im Hauptthread, und genau, du speicherst den Zeitpunkt ab, in dem die Sachen aus dem Puffer in die map kopiert werden sollen (zur erstellung also bspw. die Zeit in 3sek). Der Thread iteriert dann diese "strings"* und, wenn er sieht, dass eine Zeit mit der jetzigen übereinstimmt oder schon überfällig ist, führt er die Gewünschte Aktion aus.
    Insgesamt könnte das aber wirklich ineffizient werden. Gerade dann, wenn du nicht 3, sondern 2 oder 1 sekunden als Ablaufzeit nimmst.

    *Statt Strings, nimm einfach ein Integral und speicher die gewünschte Sekunde ab.
    z.B.:
    int i;
    Akt. Uhrzeit: ...:..:45 -> i = 45 + 3 = 48
    Im Hauptthread
    Akt. Uhrzeit: ...:..:48 -> i == 48 ->Datei in Map kopieren



  • Die Threads sollen so eine Art "Prozess" darstellen. Die sollen anschließend miteinander kommunizieren können. Der Hauptthread soll anschließend mit einem anderen Hauptthread die Daten austauschen.Die Daten sollen den nächsten Zeitschritt repräsentieren.

    Es ist etwas kommplizierter. Ich weiss nicht wie der hauptthread mit seinen internas kommunizieren soll ohne das Daten verloren gehen oder welche überschieriben werden!



  • Mal unter der Annahme ich habe verstanden, was Du wirklich machen willst:
    * Du hast n-Threads
    * n-1 Threads erzeugen Daten
    * 1 Thread liest diese Daten
    * zwischen erzeugen der Daten und deren "Gültig" werden soll pro Thread eine bestimmte Zeitspanne liegen. Diese Zeitspanne ist aber nur für den Thread relevant, d.h. es liegt keine gemeinsame Zeitskala zu grunde.

    Dann würde ich das so lösen, dass jeder der n-1 Threads einen vector<data> bekommt, in die er die Daten schreibt, jeder Thread hat außerdem ein Semaphor, dass er vor Beginn der Bearbeitung anfragt ("acquire"). Nach dem Ende der Schlafenszeit gibt er das Semaphor wieder frei ("release"), was gleichzeitig die Gültigkeit der Daten markiert. Der Hauptthread prüft, ob er eine der n-1 Semaphoren bekommen kann ("tryAcquire"), wenn ja, werden die Daten bearbeitet (versendet). Danach gibt er das Semaphor wieder frei, so dass der betreffende thread sich das wieder holen kann und das Spiel beginnt von vorn. Dabei brauchst Du aber noch ein zusätzliches Element, z.B. pro Thread einen Zähler, so dass der Lesethread, wenn er das Semaphor hat, schauen kann, ob neue Daten vorliegen.

    Grob gesagt:

    vector<Semaphore> semaphores; // müssen z.B. alle auf 0 initialisiert werden
                                  // größe = Anzahl Erzeugerthreads, sie dienen 
                                  // gleichzeitig dem Zugriffsschutz auf newData und data[i]
    vector<bool> newData;         // Zeigt an, ob neue Daten vorliegen
    vector<vector<threadData>> data; // Daten der einzelnen Threads
                                     // ggf. muss hier noch ein Lock her, da mehrere
                                     // threads in diese Struktur schreiben, oder man legt n-1 einzelne Variablen an.
    // im main-thread
    while (!shallTerminate())
    {
        for(size_t i = 0; i < semaphores.size(); ++i)
        {
            if (semaphores[i].tryAcquire())
            {
                if (newData[i] == true)
                {
                    // verarbeite Daten die im data-Vector an der Position des Threads stehen
                    newData[i] = false;
                }
                semaphores[i].release();
            }
            sleep(someMillisecs);
        }
    }
    
    // in jedem DatenThread
    size_t dataThreadID; // auf die Position im Vector initialisiert
    while (!shallTerminate())
    {
        if(semaphores[i].tryAcquire())
        {
            if (newData[i] == false) // sind die Daten schon abgeholt
            {
                // erzeuge Daten die im data-Vector an der Position des Threads stehen
                newData[i] = true;
            }
            else
            {
                 // potenzielle Fehlerbehandlung, weil Daten nicht schnell genug abgeholt wurden
            }
            sleep(timeout);
            semaphores[i].release();
        }
    }
    

Log in to reply