Gibt es bei Threads definierte Zustände?



  • Ich wusste nicht genau, wie ich den Thread benennen soll. Ich frage mich, wie das mit Threads ist. Sagen wir mal ich habe Thread A und Thread B. Thread A allokiert speicher und schreibt dann in den Speicher was rein. Das Betriebssystem entscheidet ja dann, wann welcher Thread dran ist. Kann es vorkommen, dass Thread A genau dann beendet wird, wenn das Allokieren des Speichers, gerade "halb vorbei" ist? Wenn also das Betriebssystem ein paar Checks gemacht hat, aber sich dann denkt, dass Thread B jetzt mal wieder dran ist. Oder gibt es bei Threading bestimmte Befehle, die auf jeden Fall erst abgearbeitet werden, bevor der nächste Thread dran ist? Ich würde mich sehr über Links zu weiterführenden Artikeln über Threading führen, in denen diese Fragen beantwortet werden. Ich hab per Google leider nichts Passendes gefunden, aber das Thema interessiert mich wirklich sehr!



  • Es kommt darauf an, wie der Thread beendet wird. Wenn du den Thread gewaltsam "terminierst" kann es durchaus vorkommen, dass er gerade in einem syscall ist um Speicher anzufordern. Das Betriebssystem kommt aber normalerweise damit zurecht und weiss welcher Thread welche Ressourcen angefordert hat und kann diese wieder freigeben.
    Um zu verstehen wie genau das Threading bzw. Multitasking funktioniert, solltest du dir mal Artikel über Multitasking durchlesen (beide Arten kooperativ und verdrängend). Wenn du das verstanden hast, kannst du dir so gut wie alle Fragen über Multithreading selbst beantworten.



  • threader schrieb:

    ... Wenn also das Betriebssystem ein paar Checks gemacht hat, aber sich dann denkt, dass Thread B jetzt mal wieder dran ist. Oder gibt es bei Threading bestimmte Befehle, die auf jeden Fall erst abgearbeitet werden, bevor der nächste Thread dran ist?

    Ja, es gibt solche "un-unterbrechbaren" Sequenzen.
    Das OS verwendet diese intern.

    Ein normales Usermode Programm kann aber auf den meisten Betriebssystemen nicht "erzwingen" dass es nicht unterbrochen wird. Unter Windows 95 ging es noch, da konnte man einfach mit "cli" alls Interrupts sperren, und mit gesperrten Interrupt wurde der Thread eben nicht unterbrochen. (Weil zum Unterbrechen üblicherweise - und so auch bei Win95 -- ein Timer-Interrupt verwendet wird.)
    Auf Windows NT basierten Systemen geht es nicht mehr (*).

    Ein Treiber bzw. natürlich auch das OS selbst kann aber wie gesagt verhindern dass ein Thread schlafen gelegt wird. Auf Windows NT basierten Systemen setzt man dazu normalerweise einfach den "IRQL" mittels KeRaiseIrql auf DISPATCH_LEVEL oder höher.

    Ein bisschen was zu dem Thema steht hier beschreiben: http://msdn.microsoft.com/en-us/windows/hardware/gg487402.aspx

    Im Kapitel "Interrupt Request Levels" steht z.B.:

    When a processor is running at a given IRQL, interrupts at that IRQL and lower are masked off (blocked) on the processor. For example, a processor that is running at IRQL=DISPATCH_LEVEL can be interrupted only by a request at an IRQL greater than DISPATCH_LEVEL.

    The system schedules all threads to run at IRQLs below DISPATCH_LEVEL, and the system’s thread scheduler itself (also called “the dispatcher”) runs at IRQL=DISPATCH_LEVEL. Consequently, a thread that is running at or above DISPATCH_LEVEL has, in effect, exclusive use of the current processor. Because DISPATCH_LEVEL interrupts are masked off on the processor, the thread scheduler cannot run on that processor and thus cannot schedule any other thread.

    Soweit ich weiss ist das auch der einzige offiziell supportete Weg um auf Windows NT basierten Systemen zu verhindern dass ein Thread unterbrochen wird.

    Und, evtl. auch interessant: den IRQL anzuheben verhindert nicht Thread-Wechsel auf anderen CPUs/Cores.

    Und was dein Beispiel mit dem Speicher-Anfordern angeht: kann ich nicht konkret sagen ob das OS da Thread-Wechsel verhindert. Ich würde vermuten dass nicht. Man kann aber gute Argumente dafür und dagegen finden. Du kannst dich aber auf jeden Fall drauf verlassen, dass, auch wenn ein speicher-anfordernder Thread unterbrochen wird, nichts schlimmes passiert. Weil der Zugriff auf die zur Heap-Verwaltung verwendeten Strukturen mit entsprechenden Locks abgesichert ist. D.h. wenn Thread A unterbrochen würde, und dann Thread B losläuft, und der auch Speicher anfordern will, dann muss Thread B einfach so lange warten bis Thread A wieder Zeit bekommen hat, und seine Speicheranforderung abschliessen konnte. Bis dahin wird Thread B dann einfach schlafen gelegt. Stichworte: Mutual-Exclusion (Mutex), Spin-Lock oder CRITICAL_SECTION.

    *:
    D.h. genaugenommen kann ein Windows Programm Thread-Wechsel verhindern, wenn es mit Admin-läuft Rechten und das einen ggf. passend signierten Treiber mitbringt. Indem es den Treiber "on demand" installiert, startet und dann eben verwendet.



  • Schon mal danke für die Antworten.

    Ich hab mir schon ein wenig was durchgelesen, auch dieses Dokument, das hustbaer verlinkt hat, ist sehr interessant.

    Mir fehlt aber immer noch die Information, welche Garantien man bei Threading im Bezug auf Zustände hat.

    Noch ein Beispiel:

    Ich habe zwei Threads, die die gleiche Funktion aufrufen. Diese Funktion allokiert Speicher und schreibt die Adresse dieses Speichers dann in einen Pointer. Es werden keine Locks verwendet. Kann es dann zu undefinierten Zuständen kommen? Das Schreiben einer Adresse in einen Pointer besteht ja nicht nur aus einem einzigen Befehl auf dem Prozessor.

    Das was hustbaer vermutet, geht ja in die Richtung. Dass also sozusagen der Thread, der mit dem Allokieren angefangen hat, es dann auch zuende bringen darf, bevor ein anderer Thread Speicher allokiert. Aber wo steht geschrieben, dass ich auf jeden Fall davon ausgehen kann? Vielleicht brauche ich auch einen technischen Artikel, in dem ganz klar gesagt wird, wann man Locks verwenden muss, um undefinierte Zustände zu vermeiden.



  • Bzgl. lock bei Funktionen solltest du dich mal zum Stichwort reentrant bzw. reentrency informieren, z.B. http://en.wikipedia.org/wiki/Reentrancy_(computing)



  • threader schrieb:

    Das was hustbaer vermutet, geht ja in die Richtung. Dass also sozusagen der Thread, der mit dem Allokieren angefangen hat, es dann auch zuende bringen darf, bevor ein anderer Thread Speicher allokiert. Aber wo steht geschrieben, dass ich auf jeden Fall davon ausgehen kann? Vielleicht brauche ich auch einen technischen Artikel, in dem ganz klar gesagt wird, wann man Locks verwenden muss, um undefinierte Zustände zu vermeiden.

    Wozu sollte das garantiert werden? Es muss nur garantiert sein, dass eine allokation sicher ist, ob ein thread dabei suspended wird oder nicht kann von OS zu OS anders sein. auch ob waerend einer allokation und dem suspend von einem thread ein anderer durchlaufen darf/kann.
    Es kann z.B. sein, dass:
    -thread verschiedene groessen allokieren und deswegen in verschiedenen 'buckets' arbeiten, unabhaengig voneinander
    -threads auf verschiedenen cores/cpus laufen und deswegen unterschiedliche buckets haben (je nach architektur macht es z.B. sinn so zu allokieren dass der reale speicher direkt an dem cpu socket angeschlossen ist)
    -es kann sein dass die cpu keine direkten atomics hat sondern nur reservations. du kannst die zwar nutzen um ein lock zu implementieren, du kannst aber auch eine reservation direkt auf der verwaltungsstruktur machen, dann fuehrst du deine allokationen aus und 'submittest' die changes, falls dein thread dabei suspended wird, schlaegt der submit fehl, was aber bedeutet dass in der zwischenzeit ein anderer thread eine erfolgreiche allokation machte und das alles ganz ohne zutun des OS.
    -in manchen OS sorgt ein lock dazu, dass an der zweite thread der lockt suspended wird und dieser core dann wieder mit dem vormals suspended thread arbeitet, bis dieser den lock loslaesst um dort mit dem urspruenglich laufendem thread weiter zu arbeiten (das ist vor allem so wenn thread priorities nicht wie bei windows als gewichtung fuer time slices genommen werden, sondern garantiert die highest priority threads laufen wenn es moeglich ist).



  • In welchem Zustand ist den dieser Thread hier?



  • CLOSED


Anmelden zum Antworten