boost::thread:id to string



  • Hallo,

    wie wandle ich boost::thread::id in eine Zahl / String?

    Mein versuch war

    boost::thread::id thread_id(boost::this_thread::get_id());
    
    std::stringstream ss;
    ss << thread_id;
    

    Dies führt zu einem String ala "0x1e01f10". Ist das unter Ubuntu korrekt?
    Hatte eine Zahl zwischen 0 und 20 erwartet.

    Gruß, Thomas



  • Siassei schrieb:

    Dies führt zu einem String ala "0x1e01f10". Ist das unter Ubuntu korrekt?
    Hatte eine Zahl zwischen 0 und 20 erwartet.

    std::cout << "Thread ID: " << boost::this_thread::get_id();



  • boost::thread::id (was von boost::this_thread::get_id() zurückgegeben wird) ist nicht viel mehr als ein Wrapper um einen Zeiger. Was du da kriegst, ist eine Speicheradresse, und die wird schon richtig sein.

    Du kannst natürlich, wenn du willst, in einer std::map oder so den Thread-IDs Zahlen zuweisen, aber Boost.Thread macht das meines Wissens selbst nicht.



  • seldon schrieb:

    boost::thread::id (was von boost::this_thread::get_id() zurückgegeben wird) ist nicht viel mehr als ein Wrapper um einen Zeiger. Was du da kriegst, ist eine Speicheradresse, und die wird schon richtig sein.

    Du kannst natürlich, wenn du willst, in einer std::map oder so den Thread-IDs Zahlen zuweisen, aber Boost.Thread macht das meines Wissens selbst nicht.

    Ist die Speicheradresse über die Laufzeit des Thread konstant?
    Heist das, dass eine Nummerierung von mir selbst vergeben werden muss?

    Macht das pthread & Co. nicht automatisch?
    z.B.
    - Prozess 1
    - Thread 1
    - Thread 2
    - ...
    - ...



  • Siassei schrieb:

    Ist die Speicheradresse über die Laufzeit des Thread konstant?

    Ja.

    Siassei schrieb:

    Heist das, dass eine Nummerierung von mir selbst vergeben werden muss?

    Wenn du eine haben willst, ja.

    Siassei schrieb:

    Macht das pthread & Co. nicht automatisch?
    z.B.
    - Prozess 1
    - Thread 1
    - Thread 2
    - ...
    - ...

    Nein. Pthread macht mit Prozessen sowieso nichts, und davon abgesehen arbeitest du anscheinend mit Boost.Thread, nicht mit pthread direkt. Es gibt im POSIX-Standard die Möglichkeit, die Prozess-ID abzurufen (getpid()), aber diese wird vom Betriebssystem in unspezifizierter Weise zugeteilt und gilt auch systemweit. Du kannst da also nicht damit rechnen, Prozess-IDs 1, 2, 3 etc. zu bekommen, zumal die PID 1 eh für init reserviert ist.


  • Administrator

    Wozu brauchst du diese ID überhaupt? Du weisst, dass die boost::thread::id Klassen Vergleichsoperatoren hat und dadurch in z.B. einer std::map als Schlüssel verwendet werden kann.

    Grüssli



  • Vielen Dank für euere Antworten.

    Du kannst da also nicht damit rechnen, Prozess-IDs 1, 2, 3 etc. zu bekommen, zumal die PID 1 eh für init reserviert ist.

    Das muss ich nicht haben. Mir reicht ein konstanter Wert, wie es boost liefert.

    Wozu brauchst du diese ID überhaupt?

    Ich habe mir heute ein eigenes Logging-Framework gebastelt. Hier wird für die Rückverfolgung die Thread-Id für jede Aktion mit aufgezeichnet.


  • Administrator

    Und wozu brauchst du dann die boost::thread::id ? Du willst die doch nicht etwas mitausgeben? Dazu nimmst du doch viel besser einen Namen für den Thread. Den Namen kannst du in thread-lokalen Speicher halten. In C++11 gibt es dazu das Schlüsselwort thread_local . Mit Boost kannst du boost::thread_specific_ptr<T> verwenden.

    Grüssli



  • Dravere schrieb:

    In C++11 gibt es dazu das Schlüsselwort thread_local . Mit Boost kannst du boost::thread_specific_ptr<T> verwenden.

    thread_specific kannt ich bis jetzt noch gar nicht. Scheint eine gute Idee zu sein. Leider finde ich keine gute Doku hierzu.
    - Kannst du ein kleines Beispiel hierzu (C++11 und boost::thread_specific_ptr) geben?

    Danke


  • Administrator

    Doku? So schwer sollte dies doch nicht zu verstehen sein? Irgendwas in diese Richtung:

    class Logger
    {
    private:
      static thread_local char const* thread_name;
    
    public:
      static void register_name(char const* name)
      {
        thread_name = name;
      }
    };
    

    Jeder Thread ruft halt register_name auf mit dem Namen, welcher er verwenden will. Die Variable thread_name ist für jeden Thread separat vorhanden. thread_local ist aber bisher nach meinem Wissen noch von keinem Kompiler unterstützt. Obwohl dies ein wenig verwunderlich ist, hat doch MSVC das Schlüsselwort __declspec(thread) und GCC __thread .

    Bei Boost müsste es ähnlich funktionieren:

    class Logger
    {
    private:
      static void thread_name_cleanup(char const*) {}
      static boost::thread_specific_ptr<char const> thread_name;
    
    public:
      static void register_name(char const* name)
      {
        thread_name.reset(name);
      }
    };
    
    boost::thread_specific_ptr<char const> Logger::thread_name(&Logger::thread_name_cleanup);
    

    Hab leider kein Boost hier zur Verfügung, kann es daher nicht testen.

    Grüssli



  • Hallo,

    so weit ist mir das alles klar. Bei boost::thread_specific_ptr kann man angeben, wie der Speicher wieder freigegeben wird. Aber wie sieht es bei thread_local aus? Wie kann ich hier den Standard-Delete-Operator angeben?

    Der Speicher für char* kann ja über
    - new
    - malloc
    - pool
    angefordert werden.


  • Administrator

    Siassei schrieb:

    Aber wie sieht es bei thread_local aus? Wie kann ich hier den Standard-Delete-Operator angeben?

    Stichwort: RAII.
    Die thread_local Variable kann auch eine Klasse sein mit einem Destruktur. Der Destruktur wird aufgerufen, wenn der Thread beendet wird.

    Grüssli



  • Ich denke da reden wir jetzt aneinander vorbei

    Das dürfte kein Problem sein

    class A { ... };
    thread_local A *instance = new A ();
    

    Problem?

    class A { ... };
    void* raw = malloc (sizeof (A));
    thread_local A *instance = new A(raw)();
    
    // instance->~A();
    // free (instance);
    

    Problem?

    class A { ... };
    thread_local A *instance = myPool.getInstance<A> ();
    
    // myPool.destroy (instance);
    

  • Administrator

    Wieso nimmst du immer einen Zeiger? Nimm RAII! Nimm einen Container, welcher den Speicher verwaltet. Also z.B. für einen Namen:

    static thread_local std::string thread_name;
    

    Wenn du mit einem Pool arbeitest, brauchst du halt einen Smart Pointer dafür:

    static thread_local pool_ptr<A> instance = myPool.getInstance<A>();
    

    In seinem Destruktur gibt er den Speicher frei im Pool.

    Grüssli



  • ⚠ Brett vorm Kopf ⚠



  • @Dravere: Es heißt übrigens Destruktor 😉


  • Administrator

    314159265358979 schrieb:

    @Dravere: Es heißt übrigens Destruktor 😉

    Weiss ich doch.
    *sich fragt, wieso pi diese Aussage macht*
    *seine Beiträge nachlesen geht*
    ... hö? 😮 ... 😕

    *nach Erklärungen sucht*
    Ich hatte noch keinen Kaffee! 😃

    Grüssli


Anmelden zum Antworten