Ich führe zwei Threads (nehme an, dass sie für den Moment Pthreads sind). Thread_1 () führt einen benutzerdefinierten API-Aufruf durch, der letztendlich im Kernel funktioniert. Thread_2 () befindet sich vollständig im Benutzerbereich.
Meine Frage ist: Kann Thread_2 () mit der Ausführung von Thread_1 () beginnen, während der API-Aufruf läuft, das Steuerelement befindet sich irgendwo im Kernel? Wenn nicht, warum und wenn ich möchte, dass dieses Szenario auftritt (aus welchen Gründen auch immer), was muss ich tun?
Wenn Sie fragen, ob ein blockierender Kernel-Aufruf wie ein fread()
, der Disk-IO benötigt, vorweggenommen werden kann, dann ja.
Genauer gesagt wird ein blockierender Aufruf Thread_1 in den Ruhezustand versetzen, während er auf alles wartet, worauf er wartet. Wenn Thread_1 inaktiv ist, wird Thread_2 für die Ausführung geplant (es sei denn, eine höhere Priorität wartet darauf, ausgeführt zu werden).
Bearbeiten: Wenn Sie sichergehen möchten, dass Thread_1 einen blockierenden Anruf durchführt, machen Sie Thread_2 eine niedrigere Priorität als Thread_1 (so dass es im Allgemeinen nicht run, wenn Thread_1 nicht blockiert ist und wenn es ausgeführt wird, erhöht es seine Priorität auf eine höhere Ebene als Thread_1, bis der Hardware-Interrupt ausgelöst wurde. An diesem Punkt wird die Priorität gesenkt und sched_yield()
aufgerufen.
Aufrufe an den Kernel werden entweder als blockierend oder nicht blockierend betrachtet. Ein blockierender Anruf (z. B. Warten auf das Lesen von Daten von einem Netzwerk-Socket) kann mit Sicherheit verhindert werden, ohne dass Ihrerseits eine Aktion erforderlich ist. Andere Threads werden weiterhin ausgeführt. Nicht blockierende Kernel-Aufrufe können als sehr schnell angesehen werden, und in der Praxis spielt es keine Rolle, ob Sie sie tatsächlich vorgreifen können oder nicht.
Wenn Sie Multithreading-Code schreiben, konzentrieren Sie sich im Allgemeinen darauf, wie diese Threads miteinander interagieren und überlassen ihre Interaktion mit dem Kernel dem Kernel, um ihn zu verwalten. Es wurde entwickelt, um einen ziemlich guten Job zu machen.
Das hängt vom Kernel ab. Klassische Kernel erlaubten keine Vorkaufsrechte (außer an bestimmten Punkten, an denen ein Thread schlafen würde). Aber neuere Kernel haben damit begonnen, Preemption innerhalb des Kernels selbst zu aktivieren.
Linux unterstützt einen präemptiven Kernel, wenn er mit CONFIG_PREEMPT erstellt wird. Aus der Kernel-Dokumentation:
Diese Option reduziert die Latenz des Kernels durch make aller Kernel-Code (der nicht in einem kritischen Abschnitt ausgeführt wird) präemptiv. Dies ermöglicht eine Reaktion auf interaktive Ereignisse durch damit ein Prozess mit niedriger Priorität unfreiwillig verhindert werden kann auch wenn es im Kernel-Modus einen Systemaufruf ausführt und würde andernfalls wäre es nicht möglich, einen natürlichen Vorzugspunkt zu erreichen. Dies ermöglicht es Anwendungen, "reibungsloser" zu laufen, selbst wenn die System ist unter Last, auf Kosten von etwas niedrigeren Durchsatz und ein geringer Laufzeitaufwand zum Kernel-Code.
Wählen Sie diese Option, wenn Sie einen Kernel für einen Desktop erstellen oder eingebettetes System mit Latenzanforderungen in Millisekunden Bereich.
Tags und Links c c++ multithreading pthreads