Threads Verständnisfragen



  • Hallo, dies ist quasi der Fortsetzungsthread zu einem anderen Problem, das ich hatte (http://www.c-plusplus.net/forum/viewtopic-var-p-is-1318403.html#1318403).
    Da es aber eigentlich ein neues Thema ist, habe ich einen neuen Thread eröffnet.

    Ich möchte Teile meines Programm (Daten-Updates aus dem INet) in einem eigenen Thread laufen lassen.

    Dazu habe ich auch Beispiel-Code gefunden, der mit '_beginthread' (process.h) arbeitet. Frage mich aber nach einigen Recherchen, welche 'Technik' vorzuziehen ist. Aus den MSDN-Artikeln geht das für mich nicht hervor:
    - beginthread
    - CreateThread
    - CreateThreadEx

    Anscheinend gibt es bei den CreateThread u.U. Probleme (Memoryleaks/Abbrüche). Die API hat aber wohl auch vorteile (von extern beenden etc.)

    Was ist denn vorzuziehen?

    Und jetzt noch eine Design-Frage:
    Mein Programm erstellt WinMain eine Instanz von meinem 'Root-Objekt', das letztlich auch die Main-Loop ausführt. Vor der MainLoop wurde bisher ein 'updateDaten' aufgerufen, damit ein vector (vector.h) mit anzuzeigenden Instanzen gefüllt ist.

    Im Multithreading-Betrieb sollte genau dieser 'updateDaten'-Bereich von einem neuen, eigenen Thread erledigt werden (initial und später zeitgesteuert). Mein 'Root-Objekt' kann ich dem Thread ja als Parameter übergeben, ich frage mich jetzt aber, wie ich den Zugriff auf den Vector synchron gestallte. Ich habe zwar von Mutexen (Plural so korrekt?!) gehört und gelesen, habe aber keine Ahnung, wie ich die auf den Vector oder dessen Elemente anwende.
    Der Zugriff auf Attribute der Elemente geschieht direkt, weil mir Accessoren in C++ zu umständlich sind. Letzlich soll das Element an sich ja auch konsistent sein, es sollte also erst gelesen werden, wenn es vollständig (upgedatet) ist.

    Gebt mir doch bitte mal einen Tip. Die Lösung habe ich einfach nichr per Suche gefunden.



  • ja mutex ist schon mal derrichtige ansatz... deinem hauptthread und deinem extra thread bedienen sich von einem Mutex- Objekt...

    schau mal nach mutex. Lock und Unlock... damit können daten die geschreien /gelesen werden für die anderen trhead (die das mtuex objekt benutzen) blockeirt werden bzw. diese thread werden dann solange schalfen geleget bis daws mutext objekt (unlock) wieder frei ist..

    thread A:
    lock
    vector schreiben
    unlock

    thread B:
    lock
    vector lesen
    unlock



  • ich würde das über einen shared_ptr + mutex lösen:

    global: (bzw. für beide threads sichtbar)
    
    mutex m
    shared_ptr<daten> aktuelle_daten
    
    ---
    
    daten lesen:
        shared_ptr<daten> neue_daten = new daten
    
        neue_daten befüllen
    
        m.lock
        aktuelle_daten = neue_daten
        m.unlock
    
    daten anzeigen:
        m.lock
        shared_ptr<daten> d = aktuelle_daten
        m.unlock
    
        d anzeigen
    

    hat den vorteil dass du während du die daten anzeigst keine mutex gelockt halten musst, und während des auslesens auch nicht.

    ansonsten... wenn vielleicht jemand ein gutes buch/paper empfehlen kann? ich kann es leider nicht (etwas empfehlen), ich hab' mir das alles mühsam "zusammengekämpft" aus 100 verschiedenen quellen. und das thema ist leider viel zu komplex um es in ein paar postings zu erklären.



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Das mit em Shared Pointern hört sich gut an.
    Ich müßte in meinem Fall also ein
    shared_ptr<vector> aktuelle_daten definieren und bei jedem Zugriff einen Mutex drum 'klammern'. Richtig?
    Um die Mutex-Sperre kurz zu halten wird in beiden Fällen so lang wie möglich auf Kopien gearbeitet. Auch richtig?

    Ich habe auch schon darüber nachgedacht, dass mein zweiter 'Zuliefer'-Thread die neuen Daten an ein beiden bakanntes Objekt übergibt und der erste dann für die Einpflege sorgt, so bleiben die eigentlichen Daten unter der Kontrolle des ersten Threads. Ist aber natürlich nicht ganz so schön.

    Wie beende ich den Thread eigentlich wieder? Der soll ja durchlaufen und alle x Minuten updates liefern. Wenn das Prg. beendet wird, wäre es ja sauber, wenn der Main-Thrad ihn beendet.



  • Beenden kannst du z.B. so, indem du im lese-Thread nicht einfach Sleep(1000) oder so machst, sondern WaitForSingleObject(eventHandle, 1000). Event ist dann eben ein manual-reset-event (->CreateEvent) der vom Hauptthread gesetzt wird wenn der lese-Thread terminieren soll.
    WaitForSingleObject liefert im Normalfall dann WAIT_TIMEOUT zurück, und wenn der Event "signaled" ist eben WAIT_OBJECT_0.

    Der Hauptthread geht also her und setzt den Event und wartet danach mit WaitForSingleObject(threadHandle, INFINITE) darauf dass der lese-Thread sich beendet hat.



  • Super! Danke!
    Die Art und Weise habe ich bei Prozessen schon mal gesehen. Damit werd' ich's mal versuchen.
    Thx so far.

    Was ist mit den anderen Punkte? Hatte ich Dich richtig verstanden?
    😋 Bestimmt, sonst hättest Du etwas gesagt.



  • Ich denke du hast das richtig verstanden, ja.

    Wichtig ist eben dass du mittels Mutexen sicherstellst dass nicht mehrere Threads gleichzeitig auf die Daten zugreifen können (zumindest sobald ein Thread dabei ist der etwas schreibt).



  • Da setze ich mich doch gleich mal ran. Ich werde aber ein 'Austausch'-Objekt nehmen, über das die Threads kommunizieren. Dann bekommt der erste es wenigstens auch mit, wenn sich etwas geändert hat.

    😋 Mal was neues, dass ich bei C++ etwas verstanden habe.

    -------

    Hat scheinbar alles funktioniert:
    gemeinsame Api-Klasse für 3 Threads, die die Datenzugriffe mit einem Mutex kapselt. Thread 2 und 3 arbeiten in einer Schleife mit WaitForSingleObject und werden über Events gesteuert.

    DANKE!!!


Anmelden zum Antworten