boost::thread neu starten / boost::thread id welcher wert?



  • Ich stehe vor folgendem Problem: Ich benutze Boost::thread und ich habe ein Container mit threads, jetzt will ich aber nicht jedes mal wnen ich einen neuen thread brauche einen neuen hinzufügen sondern erstmal gucken ob ein alter vll fertig ist. Nun bin ich mir aber net sicher wie das geht, nur das jeder thread eine ID hat die bei beenden auf not-a-thread gesetzt wird, welchem wert entspricht das? bzw wie finde ich das raus?

    Die zweite sache ist, wie starte ich den thread neu?

    mfg Jud4s

    danke für die Tipps/Ideen



  • kann nur allgemein antworten, mit boost::threads hab ich noch ned so viel gemacht.

    Die zweite sache ist, wie starte ich den thread neu?

    Kurz: gar nicht !
    leuft dein thread aus ... sprich Du(terminate -> boese) oder Er selber(die threadProc laueft aus) beendet sich, ist der Thread fuer Dich verloren. Restarten geht nicht, sondern nur komplett neu kreieren.

    Willst du einen thread nicht auslaufen lassen, sondern immer weiter verwenden, solltest du ihn, wenn er mit der ersten aufgabe fertig ist, auf ne Syncvariable laufen lassen. Maximal vielleicht noch suspendieren (iss aber nicht notwendig, wenn die variable kein spinlock macht) und wenns wieder was zu tun gibt, den thread von der syncvariable freigeben (ggf resume vorher auf den thread) und auf die neuen daten laufen lassen ...

    Ciao ...



  • duplicate



  • und wie finde raus ob ein thread noch läuft? Also mit welchen wert muss ich die ID vergleihen um das rausfinden?

    gibt es eine Möglichkeit das ein thread auf der Konsole einließt und ein anderer schreibt?



  • gibt es eine Möglichkeit das ein thread auf der Konsole einließt und ein anderer schreibt?

    IMHO ist std::cin und std::cout threadsicher, sollte also gehen.
    Was er liest und schreibt, steht natürlich auf einen anderen blatt.

    und wie finde raus ob ein thread noch läuft? Also mit welchen wert muss ich die ID vergleihen um das rausfinden?

    Wenn es sich dabei um die ThreadID handelt:
    die solltest mit gar nix vergleichen. Die threadID wird dir vom system generiert, um einen thread eindeutig identifizieren zu koennen. nix weiter. Ob der thread noch lauft oder nicht, kannst nich an der threadID ablesen.

    was du aber machen kannst, ist:

    - Dein thread signalisiert deinen "mainthraed" kurz bevor er auslaeuft. Das musst selber implementieren.

    - dein mainthread kann explicit auf das "natuerliche" Ende deines Threads warten. Dafuer gibts in boost::thread sicher auch ne funktion. Die gibt auch den Exitstatus deines Threads zurueck.
    Rufst du die funktion auf, und dein thread iss scho lange ausgelaufen, dann kehrt die funktion sofort zurueck, und gibt den exitstatus zurueck.
    (zum "proben" ob ein thread laeuft, kannst die nich benutzen, weil die erst zurueckkehrt wenn der thread ausgelaufen iss)

    mehr hasst du ned wirklich zur verfuegung und solltest auch nicht nutzen !

    "Normal" baut man Apps so, das die Verwaltung die Threads fuehrt, wenn sie kreiert wurden sind. wenn die auslaufen, benachrichtigen sie die Verwaltung (also kurz vorm auslaufen), die verwaltung wartet dann auf das richtige Ende und loescht den Thread (aus seiner Verwaltung).
    Ausgelaufene threads im system zu verwalten macht kein sinn ...

    "Normal" sollte sich nen Thread staendig mit der App unterhalten, und neue daten zum bearbeiten bekommen, und wenn er die abgearbeitet hat, den mainthread benachrichtigen, der holt dann die daten ab und gibt den thread neues zu tun ... in den "pausen" wartet der thread (auf daten).

    Les Dich mal bissi in Thread und Synchronisation ein ... Ohne fundamentales wissen faellst da ziemlich schnell auf den mund. und die boost hilft dir da auch ned wirklich weiter ... Ich find z.b. die Schnittstelle der boost::thread ned wirklich intuitiv, ich komm mit windows nativ threads besser klar, auch pthreads schaut auf dem ersten blick intuitiver aus.
    Aber boost::thread iss natuerlich portabel, dasn riesen vorteil, wenn man ihn denn nutzt 🙂

    Ciao ....



  • RHBaum schrieb:

    gibt es eine Möglichkeit das ein thread auf der Konsole einließt und ein anderer schreibt?

    IMHO ist std::cin und std::cout threadsicher, sollte also gehen.
    Was er liest und schreibt, steht natürlich auf einen anderen blatt.

    Es ist eben NICHT Thread-safe. Die Funktionen werden nicht atomar ausgeführt und sind somit nicht Thread-safe.

    btw:
    Völlig falsche Verwendung der Abkürzung "IMHO". Das hat nichts mit deiner Meinung zu tun. 😉



  • hmm, werde das schon irgendwie gelöst bekommen, mit der ein und ausgabe...ist eh nicht so wichtig... eigtl nur für testzwecke...

    Mein Hauptproblem sind aber immer noch diese Threads. Ich habe nämlich eine Klasse deren Objekte mehrmals ausgeführt werden sollen... bzw verständlicher von der mehrere Objekte erzeugt werden sollen deren Methoden dann parallel laufen. Da ich aber eine undefiniert kleine/hohe Anzahl solcher Objekte verwenden möchte habe ich mir überlegt eine Handlerklasse zu machen die die Threads und die verwendeten Objekte in einem Vector speichert, nun möchte ich aber nicht jedes mal wenn ich eines dieser Objekte "starten" möchte ein neuen thread zu dem Vector adden, der wird nur unsinnig groß. Also brauche ich einen Weg mit dem ich herrausfinde welcher der Threads nicht läuft um diesen dann zu löschen (bzw da ich vorhabe das auf dem heap zu machen dann den zeiger neu zu verwenden).

    Wenn es sich dabei um die ThreadID handelt:
    die solltest mit gar nix vergleichen. Die threadID wird dir vom system generiert, um einen thread eindeutig identifizieren zu koennen. nix weiter. Ob der thread noch lauft oder nicht, kannst nich an der threadID ablesen.

    auf die Idee bin ich nur gekommen da bei der boost doku steht das die ID bei einem Thread der nicht am laufen ist auf Not-A-thread gesetzt wird. Meines erachtens die leichteste Weg herrauszufinden ob ein thread gerade läuft oder nicht....



  • Mach doch einen Funktor der eine bestimmte Anzahl deiner Objekte hintereinander aufruft.

    template<typename Iter>
    struct CallObjects
    {
      CallObjects(Iter first, Iter last):
       f(first), l(last)
      {}
      void operator()(){
        for(;f!=l; ++l)
         *f->doit();
      }
    };
    
    typedef std::vector<myFunc> V;
    V v;
    std::generate_n(std::back_inserter(v), 10, CreateFunc);
    
    boost::thread_group tg;
    size_t threads = GetMaxThreads();
    
    for(size_t n = 0; n < threads; ++n)
      CallObjects c(von_iter, bis_iter);
      tg.create_thread(c);
    

    Wenn deine Objekte in einem RandomAccess Container liegen, kannst du auch OpenMPs #pragma omp parallel for benutzen.

    Hm.. oder ist es so, dass nicht alle Objekte gleichzeitig starten sollen und später noch welche dazukommen? Dann könntest du ein paar threads starten, die sich aus einem Buffer bedienen. Ist dieser leer, warten die Threads ( boost::condition_variable::wait ). Ist er "voll", wartet der hinzufügene Thread (Producer).



  • Die objekte müssen zu einem unbestimmten zeitpunkt im Programm neu erstellt und gestartet werden... deswegen ja die Handlerklasse....nur wie finde ich jetzt raus ob ein thread noch läuft oder nicht?



  • Das macht man nicht. Lass den Thread seine Arbeit erledigen. Wenn er fertig ist, nimmt er sich selber die nächste Aufgabe. Wenn es grad keine gibt wartet er mit boost::condition_variable::wait siehe letztes posting.


Anmelden zum Antworten