Id des Primary Threads



  • Hallo alle,

    weiß jemand, wie man die Id des Primary Threads herausfinden kann? Ich meine den Thread, den das System automatisch erzeugt, wenn ein Programm gestartet wird. In der MSDN oder in den FAQs hier habe ich dazu nichts gefunden.

    Mir würde es auch genügen, wenn ich feststellen könnte, ob eine Funktion im Primary Thread aufgerufen wird oder in einem anderen Thread.

    In main() GetThreadId() aufzurufen und die Id dann zu speichern, nützt mir übrigens nichts.

    Danke!

    Stefan.



  • Thread-Sucher schrieb:

    In main() GetThreadId() aufzurufen und die Id dann zu speichern, nützt mir übrigens nichts.

    Wieso nicht?



  • Würde mich auch interessieren. :xmas1:



  • Es gibt keinen Primär Thread, sondern nur einen "First-Thread". Dieser kann aber schon lange beendet sein, wenn Du ihn erfragen willst.
    Siehe auch:
    http://blog.kalmbachnet.de/?postid=65

    WARUM willst Du diesen Thread wissen? Was willst Du mit dem machen?



  • MFK schrieb:

    Thread-Sucher schrieb:

    In main() GetThreadId() aufzurufen und die Id dann zu speichern, nützt mir übrigens nichts.

    Wieso nicht?

    Die Abfrage soll in einer Library stattfinden. Und der Programmierer der Library (das bin ich *g) ist ja nicht unbedingt der Programmierer von main(). Wollte ich also die Id des Primary Threads auf diese Weise bekommen, müsste ich den User der Library zwingen, mir diese zu übergeben. Was ich nicht akzeptabel finde.

    @ Jochen Kalmbach
    Ursprünglich wollte ich diese Information, um zu verhindern, dass eine bestimmte Funktion aus einem anderen Thread heraus aufgerufen wird.

    Eigentlich aber war das Ziel, zu verhindern, dass schon andere Threads laufen, wenn diese Funktion aufgerufen wird. Der Hintergrund ist schlicht der, dass die Funktion Daten sammelt, die später im Programm sehr oft abgefragt werden, ohne dass sie sich noch einmal ändern (Metadaten über Klassen im Programm). Aus Performancegründen möchte ich mir einfach die Mutex sparen. Denn, wie gesagt, wenn man die Daten abfragt, ändert sich sowieso nichts mehr.

    Ich sehe jetzt, dass ich ursprünglich nicht richtig nachgedacht habe. Denn wenn ich nur verhindere, dass die Funktion von einem anderen Thread als dem Primary Thread aus aufgerufen wird, verhindere ich ja nicht, dass ein anderer Thread darauf zugreift. War also irgendwie die falsche Frage.

    Stattdessen: Kann man herausfinden, wie viele Threads im Moment gerade laufen? Dazu habe ich noch nicht in der MSDN nachgesehen, aber vielleicht weiß das ja jemand aus dem Stegreif.

    Jochen, danke übrigens für die Aufklärung über den Primary Thread! In dieser Hinsicht bin ich ebenfalls auf die MSDN reingefallen. Hast mein Weltbild geradegerückt *g.

    Grüße,
    Stefan.



  • Ich verstehe immer Dein Problem noch nicht... und für was sollen die Mutexe sein?
    Du musst eigentlich nur eine Singleton Logik implementieren und das instanzieeren der (unveränderlichen) Instanz via Critical-Section absichern...

    Sozusagen so:

    CMeineStatischeDaten *m_pDaten = NULL;
    CCriticalSection m_CS;
    
    CMeineStatischeDaten *getStaticData()
    {
      m_CS.Enter();
      if (m_pDaten == NULL)
        m_pDaten = new CMeineStatischeDaten();
      m_CS.Leave();
      return m_pDaten;
    }
    

    Oder aber Du legst eben nur eine Instanz statisch an; diese wird dann von der CRT initialisiert, bevor die "main" aufgerufen wird.

    CMeineStatischeDaten s_MeineDaten;
    


  • Jochen Kalmbach schrieb:

    Ich verstehe immer Dein Problem noch nicht... und für was sollen die Mutexe sein?
    Du musst eigentlich nur eine Singleton Logik implementieren und das instanzieeren der (unveränderlichen) Instanz via Critical-Section absichern...

    Sozusagen so:

    CMeineStatischeDaten *m_pDaten = NULL;
    CCriticalSection m_CS;
    
    CMeineStatischeDaten *getStaticData()
    {
      m_CS.Enter();
      if (m_pDaten == NULL)
        m_pDaten = new CMeineStatischeDaten();
      m_CS.Leave();
      return m_pDaten;
    }
    

    Oder aber Du legst eben nur eine Instanz statisch an; diese wird dann von der CRT initialisiert, bevor die "main" aufgerufen wird.

    CMeineStatischeDaten s_MeineDaten;
    

    Nun, das Problem ist, dass parallel auf die Daten zugegriffen wird. Also (theoretisch) während des Aufbaus der Datenstruktur. Die Daten liegen in einer C++-Map und da wäre es schon fatal, wenn während des Aufbaus ein lesender Zugriff stattfände! Also müsste jeder Zugriff ebenfalls mit einer Mutex (oder sonstwie) geschützt werden.

    Das Ding als static Variable anzulegen, ist übrigens nicht möglich, da es die Daten, um die es geht zur Initialisierungszeit der DLL noch nicht gibt, bzw. da sie noch nicht vollständing sind. Ein undefinierter Zustand.

    BTW: Ist es nicht so, dass man eine CriticalSection nur für kurze Jobs verwenden soll? Ich meine, mich an sowas aus der MSDN zu erinnern. Bei langen Sachen lieber eine Mutex nehmen. Oder irre ich mich?

    Stefan.



  • Thread-Sucher schrieb:

    Nun, das Problem ist, dass parallel auf die Daten zugegriffen wird. Also (theoretisch) während des Aufbaus der Datenstruktur.

    Bei Meinem obigen Beispiel kann das ja nicht passieren, da der Aufbau der Datenstrukturen im Konstruktor erfolgt und dieser durch das CS gesichert ist...

    Thread-Sucher schrieb:

    BTW: Ist es nicht so, dass man eine CriticalSection nur für kurze Jobs verwenden soll? Ich meine, mich an sowas aus der MSDN zu erinnern. Bei langen Sachen lieber eine Mutex nehmen. Oder irre ich mich?

    Da irrst Du Dich... Mutexe benötigst Du nur, wenn Du *Prozessübergreifend* was absichern willst. Im selben Prozess immer nur die "leichten" CriticalSections verwenden!



  • Jochen Kalmbach schrieb:

    Da irrst Du Dich... Mutexe benötigst Du nur, wenn Du *Prozessübergreifend* was absichern willst. Im selben Prozess immer nur die "leichten" CriticalSections verwenden!

    Hmmm - danke für den Tip. Aber es gibt doch auch unnamed Mutexes, die nur im selben Prozess funktionieren. Für irgend etwas müssen die doch gut sein?

    Stefan.



  • Das sind binary Semaphore, die Thread-affin sind. Das heißt, nur der Thread, der den Mutex besitzt, kann ihn auch selber wieder hergeben. Diese Mutexe dürften minimal schneller als Semaphore sein. Aber der Geschwindigkeitsvergleich ist eh recht sinnfrei. Wichtig ist, dass Threads möglichst selten synchronisiert werden müssen und wenn man erwartungsgemäß nur ganz kurz wartet, kann man einen SpinWait verwenden, was teure Kontextwechsel vermeidet (trifft nur auf Multicore-Maschinen zu - auf Singlecore ist ein Spinwait vergleichbar mit normalem Warten).

    Solche Dinge zu beachten ist viel wichtiger und besser als eine CriticalSection zu verwenden die vielleicht minimal schneller synchronisiert, wo ein Mutex logisch aber angebrachter wäre.



  • Optimizer schrieb:

    Das sind binary Semaphore, die Thread-affin sind. Das heißt, nur der Thread, der den Mutex besitzt, kann ihn auch selber wieder hergeben. Diese Mutexe dürften minimal schneller als Semaphore sein. Aber der Geschwindigkeitsvergleich ist eh recht sinnfrei. Wichtig ist, dass Threads möglichst selten synchronisiert werden müssen und wenn man erwartungsgemäß nur ganz kurz wartet, kann man einen SpinWait verwenden, was teure Kontextwechsel vermeidet (trifft nur auf Multicore-Maschinen zu - auf Singlecore ist ein Spinwait vergleichbar mit normalem Warten).

    Solche Dinge zu beachten ist viel wichtiger und besser als eine CriticalSection zu verwenden die vielleicht minimal schneller synchronisiert, wo ein Mutex logisch aber angebrachter wäre.

    Sorry, aber du schreibst Mist. Eine MUTEX ist nicht minimal langsamer, sondern zig oder hundert mal langsamer. Und es gibt keinen konzeptionellen Unterschied zwischen CRITICAL_SECTION und MUTEX, eine MUTEX kann bloss etwas mehr als eine CS. Von daher gibt es auch keinen Fall wo eine Mutex "logisch angebrachter wäre" als eine CRITICAL_SECTION. Und in Windows verwendet man auch keine spin-locks, sondern man nimmt eben ne CRITICAL_SECTION (welche als spin-sleep-lock implementiert ist)

    Wenn du von Windows keine Ahnung hast solltest du dich vielleicht hier raushalten, und nicht irgendwelche Vermutungen hier rumspammen, die leider falsch sind.

    @Thread-Sucher:
    Die kurze Antwort auf "warum" ist: weil es möglich war.
    Im übrigen kannst du ein HANDLE auf so eine unnamed Mutex auch kopieren und einem anderen Prozess mitteilen -- dann kann der auch darauf zugreifen.
    Und du kannst ein MUTEX HANDLE mit WaitForMultipleObjectsEx verwenden, bzw. beim locken ein Timeout angeben -- beides Sachen die du mit einer CRITICAL_SECTION nicht kannst.


Log in to reply