Was ist der Unterschied zwischen einem Faden und einer Faser?


187

Was ist der Unterschied zwischen einem Faden und einer Faser? Ich habe von Rubinfasern gehört und ich habe gelesen, dass sie in anderen Sprachen erhältlich sind. Könnte mir jemand in einfachen Worten erklären, was der Unterschied zwischen einem Faden und einer Faser ist?

Antworten:


162

Im einfachsten Sinne werden Fäden im Allgemeinen als präventiv angesehen (obwohl dies je nach Betriebssystem möglicherweise nicht immer der Fall ist), während Fasern als leichte, kooperative Fäden angesehen werden. Beide sind separate Ausführungspfade für Ihre Anwendung.

Bei Threads: Der aktuelle Ausführungspfad kann jederzeit unterbrochen oder verhindert werden (Hinweis: Diese Anweisung ist eine Verallgemeinerung und gilt je nach Betriebssystem / Threading-Paket / etc. Nicht immer). Dies bedeutet, dass für Threads die Datenintegrität ein großes Problem darstellt, da ein Thread möglicherweise während der Aktualisierung eines Datenblocks gestoppt wird und die Integrität der Daten in einem fehlerhaften oder unvollständigen Zustand verbleibt. Dies bedeutet auch, dass das Betriebssystem mehrere CPUs und CPU-Kerne nutzen kann, indem es mehr als einen Thread gleichzeitig ausführt und es dem Entwickler überlässt, den Datenzugriff zu schützen.

Bei Fasern: Der aktuelle Ausführungspfad wird nur unterbrochen, wenn die Faser die Ausführung ergibt (gleiche Anmerkung wie oben). Dies bedeutet, dass Fasern immer an genau definierten Stellen starten und stoppen, sodass die Datenintegrität weniger ein Problem darstellt. Da Fasern häufig im Benutzerbereich verwaltet werden, müssen keine teuren Kontextwechsel und Änderungen des CPU-Status vorgenommen werden, was den Wechsel von einer Faser zur nächsten äußerst effizient macht. Da jedoch keine zwei Fasern genau zur gleichen Zeit ausgeführt werden können, werden bei alleiniger Verwendung von Fasern nicht mehrere CPUs oder mehrere CPU-Kerne genutzt.


7
Gibt es eine Möglichkeit, mehrere Threads zu verwenden, um Fasern parallel auszuführen?
Baradé

2
@Jason, Wenn Sie ~ "mit Fasern angeben, wird der aktuelle Ausführungspfad nur unterbrochen, wenn die Faser die Ausführung ergibt" und "Fasern starten und stoppen immer an genau definierten Stellen, damit die Datenintegrität viel weniger ein Problem darstellt", meinen Sie das? Wenn wir Variablen gemeinsam nutzen, müssen wir keine "Sperrmechanismen" und flüchtigen Variablen verwenden. Oder meinst du damit, dass wir diese Dinge noch tun müssen?
Pacerier

@ Baradé Es ist eine interessante Frage, hast du eine Antwort gefunden?
Mayur

57

Threads verwenden eine vorbeugende Planung, während Fasern eine kooperative Planung verwenden.

Mit einem Thread kann der Kontrollfluss jederzeit unterbrochen werden und ein anderer Thread kann übernehmen. Bei mehreren Prozessoren können mehrere Threads gleichzeitig ausgeführt werden ( simultanes Multithreading oder SMT). Daher müssen Sie beim gleichzeitigen Datenzugriff sehr vorsichtig sein und Ihre Daten mit Mutexen, Semaphoren, Bedingungsvariablen usw. schützen. Es ist oft sehr schwierig, richtig zu machen.

Bei einer Glasfaser wechselt die Steuerung nur, wenn Sie dazu aufgefordert werden, normalerweise mit einem Funktionsaufruf mit dem Namen "So" yield(). Dies erleichtert den gleichzeitigen Datenzugriff, da Sie sich nicht um die Atomizität von Datenstrukturen oder Mutexen kümmern müssen. Solange Sie nicht nachgeben, gibt es keine Gefahr, verdrängt und eine andere Faser, die versucht , die Daten zu lesen oder ändern mit dem Sie arbeiten. Wenn Ihre Faser jedoch in eine Endlosschleife gerät, kann keine andere Faser laufen, da Sie nicht nachgeben.

Sie können auch Fäden und Fasern mischen, was zu den Problemen führt, mit denen beide konfrontiert sind. Nicht empfohlen, aber manchmal kann es das Richtige sein, wenn es sorgfältig durchgeführt wird.


3
Ich denke, eine Endlosschleife ist nur ein Fehler, der behoben werden muss, und Threads haben nur dann einen ziemlich dunklen Vorteil, wenn es eine Endlosschleife gibt. Das verwandte nicht fehlerhafte Konzept ist, wenn es einen lang laufenden Prozess gibt, den der Benutzer möglicherweise abbrechen möchte. Unabhängig davon, ob Sie Threads oder Fasern verwenden, muss der Prozess mit langer Laufzeit kooperativ sein. Wenn Sie nur den Thread beenden, werden möglicherweise einige Ihrer Datenstrukturen durcheinander gebracht. Eine bessere Möglichkeit besteht beispielsweise darin, dass der Thread mit langer Laufzeit regelmäßig überprüft wird wenn es unterbrochen worden wäre. Dies unterscheidet sich nicht so sehr von einer Faser, die periodisch nachgibt.
Evgeni Sergeev

43

In Win32 ist eine Glasfaser eine Art vom Benutzer verwalteter Thread. Eine Glasfaser hat einen eigenen Stapel und einen eigenen Befehlszeiger usw., aber Glasfasern werden vom Betriebssystem nicht geplant: Sie müssen SwitchToFiber explizit aufrufen. Im Gegensatz dazu werden Threads vom Betriebssystem präventiv geplant. Grob gesagt ist eine Glasfaser ein Thread, der auf Anwendungs- / Laufzeitebene verwaltet wird, anstatt ein echter Betriebssystem-Thread zu sein.

Die Konsequenzen sind, dass Fasern billiger sind und die Anwendung mehr Kontrolle über die Planung hat. Dies kann wichtig sein, wenn die App viele gleichzeitige Aufgaben erstellt und / oder die Ausführung genau optimieren möchte. Beispielsweise kann ein Datenbankserver Fasern anstelle von Threads verwenden.

(Möglicherweise gibt es andere Verwendungen für denselben Begriff. Wie bereits erwähnt, ist dies die Win32-Definition.)


37

Zuerst würde ich empfehlen, diese Erklärung des Unterschieds zwischen Prozessen und Threads als Hintergrundmaterial zu lesen .

Sobald Sie gelesen haben, dass es ziemlich einfach ist. Threads können entweder im Kernel oder im Benutzerbereich implementiert werden, oder die beiden können gemischt werden. Fasern sind im Grunde genommen Threads, die im Benutzerbereich implementiert sind.

  • Was normalerweise als Thread bezeichnet wird, ist ein im Kernel implementierter Ausführungsthread: ein sogenannter Kernel-Thread. Die Planung eines Kernel-Threads wird ausschließlich vom Kernel übernommen, obwohl ein Kernel-Thread die CPU freiwillig freigeben kann, indem er in den Ruhezustand wechselt, wenn er dies wünscht. Ein Kernel-Thread hat den Vorteil, dass er blockierende E / A verwenden kann und den Kernel sich um die Planung kümmern kann. Der Hauptnachteil besteht darin, dass das Thread-Wechseln relativ langsam ist, da es das Einfangen in den Kernel erfordert.
  • Fasern sind User-Space-Threads, deren Planung im User-Space von einem oder mehreren Kernel-Threads in einem einzigen Prozess verwaltet wird. Dies macht das Umschalten der Glasfaser sehr schnell. Wenn Sie alle Fasern, die auf einen bestimmten Satz gemeinsam genutzter Daten zugreifen, im Kontext eines einzelnen Kernel-Threads gruppieren und deren Planung von einem einzelnen Kernel-Thread verwaltet wird, können Sie Synchronisationsprobleme beseitigen, da die Fasern effektiv seriell ausgeführt werden und Sie vollständig sind Kontrolle über ihre Planung. Das Gruppieren verwandter Fasern unter einem einzelnen Kernel-Thread ist wichtig, da der Kernel-Thread, in dem sie ausgeführt werden, vom Kernel vorbelegt werden kann. Dieser Punkt wird in vielen anderen Antworten nicht klargestellt. Wenn Sie blockierende E / A in einer Faser verwenden, ist der gesamte Kernel-Thread Teil von Blöcken, einschließlich aller Fasern, die Teil dieses Kernel-Threads sind.

In Abschnitt 11.4 "Prozesse und Threads in Windows Vista" unter modernen Betriebssystemen kommentiert Tanenbaum:

Obwohl Fasern kooperativ geplant werden, ist bei mehreren Threads, die die Fasern planen, eine sorgfältige Synchronisation erforderlich, um sicherzustellen, dass sich die Fasern nicht gegenseitig stören. Um die Interaktion zwischen Threads und Fasern zu vereinfachen, ist es häufig nützlich, nur so viele Threads zu erstellen, wie Prozessoren zum Ausführen vorhanden sind, und die Threads für jeden Lauf nur auf einem bestimmten Satz verfügbarer Prozessoren oder sogar nur einem Prozessor zu aktivieren. Jeder Thread kann dann eine bestimmte Teilmenge der Fasern ausführen, wodurch eine Eins-zu-Viele-Beziehung zwischen Threads und Fasern hergestellt wird, was die Synchronisation vereinfacht. Trotzdem gibt es immer noch viele Schwierigkeiten mit Fasern. Die meisten Win32-Bibliotheken kennen keine Fasern, und Anwendungen, die versuchen, Fasern so zu verwenden, als wären sie Threads, werden auf verschiedene Fehler stoßen. Der Kernel kennt keine Fasern, und wenn eine Faser in den Kernel eintritt, blockiert der Thread, auf dem sie ausgeführt wird, möglicherweise und der Kernel plant einen beliebigen Thread auf dem Prozessor, sodass andere Fasern nicht ausgeführt werden können. Aus diesen Gründen werden Fasern nur selten verwendet, außer wenn Code von anderen Systemen portiert wird, die explizit die von Fasern bereitgestellte Funktionalität benötigen.


4
Dies ist die vollständigste Antwort.
Bernard

12

Beachten Sie, dass Windows 7 zusätzlich zu Threads und Glasfasern die Benutzermodusplanung einführt :

User-Mode Scheduling (UMS) ist ein einfacher Mechanismus, mit dem Anwendungen ihre eigenen Threads planen können. Eine Anwendung kann im Benutzermodus zwischen UMS-Threads wechseln, ohne den Systemplaner einzubeziehen, und die Kontrolle über den Prozessor wiedererlangen, wenn ein UMS-Thread im Kernel blockiert. UMS-Threads unterscheiden sich von Fasern darin, dass jeder UMS-Thread seinen eigenen Thread-Kontext hat, anstatt den Thread-Kontext eines einzelnen Threads gemeinsam zu nutzen. Die Möglichkeit, im Benutzermodus zwischen Threads zu wechseln, macht UMS effizienter als Thread-Pools für die Verwaltung einer großen Anzahl von Kurzarbeitselementen, die nur wenige Systemaufrufe erfordern.

Weitere Informationen zu Threads, Fasern und UMS finden Sie unter Dave Probert: Inside Windows 7 - User Mode Scheduler (UMS) .


7

Threads werden vom Betriebssystem geplant (vorbeugend). Ein Thread kann vom Betriebssystem jederzeit gestoppt oder wieder aufgenommen werden, aber Fasern verwalten sich mehr oder weniger selbst (kooperativ) und geben sich gegenseitig nach. Das heißt, der Programmierer steuert, wann Fasern ihre Verarbeitung durchführen und wann diese Verarbeitung zu einer anderen Faser wechselt.


7

Threads sind im Allgemeinen darauf angewiesen, dass der Kernel den Thread unterbricht, damit er oder ein anderer Thread ausgeführt werden kann (was besser als präventives Multitasking bekannt ist), während Fasern kooperatives Multitasking verwenden, bei dem die Faser selbst ihre Laufzeit aufgibt, damit andere Fasern können laufen.

Einige nützliche Links, die es besser erklären als ich es wahrscheinlich getan habe, sind:


7

Threads wurden ursprünglich als einfache Prozesse erstellt. In ähnlicher Weise sind Fasern ein leichter Faden, der sich (vereinfacht) auf die Fasern selbst stützt, um sich gegenseitig zu planen, indem sie Kontrolle ergeben.

Ich denke, der nächste Schritt werden Stränge sein, bei denen Sie ihnen jedes Mal ein Signal senden müssen, wenn Sie möchten, dass sie eine Anweisung ausführen (ähnlich wie bei meinem 5-jährigen Sohn :-). In den alten Tagen (und sogar jetzt auf einigen eingebetteten Plattformen) waren alle Threads Fasern, es gab keine Vorkaufsrechte und Sie mussten Ihre Threads schreiben, um sich gut zu verhalten.


3

Die Win32-Faserdefinition ist in der Tat die bei Sun Microsystems festgelegte "Green Thread" -Definition. Es ist nicht erforderlich, den Begriff Faser auf dem Thread irgendeiner Art zu verschwenden, dh einem Thread, der im Benutzerbereich unter der Kontrolle von Benutzercode / Thread-Bibliothek ausgeführt wird.

Um das Argument zu verdeutlichen, lesen Sie die folgenden Kommentare:

  • Mit Hyper-Threading kann die Multi-Core-CPU mehrere Threads akzeptieren und auf jeden Core verteilen.
  • Die superskalare Pipeline-Pipeline akzeptiert einen Thread zur Ausführung und verwendet ILP (Instruction Level Parallelism), um den Thread schneller auszuführen. Wir können annehmen, dass ein Faden in parallele Fasern gebrochen ist, die in parallelen Rohrleitungen verlaufen.
  • Die SMT-CPU kann mehrere Threads akzeptieren und sie zur parallelen Ausführung auf mehreren Pipelines in Befehlsfasern bremsen, wobei Pipelines effizienter verwendet werden.

Wir sollten davon ausgehen, dass Prozesse aus Fäden bestehen und dass Fäden aus Fasern bestehen sollten. In Anbetracht dieser Logik ist die Verwendung von Fasern für andere Arten von Fäden falsch.


Das ist interessant.
JSON
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.