2017-07-11 3 views
1

Kann eine in Thread A erstellte Faser zu einer anderen in Thread B erstellten Faser wechseln? Um die Frage spezifischer zu machen, einige Betriebssysteme haben nativ implementiert Fasern (windows fibers),
andere müssen es selbst implementieren (mit setjump longjump in Linux usw.).Können Fasern zwischen Fäden wandern?

Libcoro zum Beispiel wickelt diese in einem einzigen API up (für Windows, es ist nur ein Wrapper für native Fasern, für Linux er es implementiert selbst etc.)

Also, wenn es möglich ist, Fasern zwischen Threads zu migrieren, Kannst du mir eine Beispielverwendung in Windows (Linux) in C/C++ geben?

Ich fand etwas über die Fasermigration in der Boost-Bibliothek documentation, aber es ist nicht spezifisch genug über seine Implementierung und Plattformabhängigkeit. Ich möchte immer noch verstehen, wie ich es selbst mache, indem ich zum Beispiel nur Windows-Fasern benutze (oder Libcoro unter Linux benutze).

Wenn es in einem allgemeinen Weg nicht möglich ist, warum so?

Ich verstehe, dass Fasern als lightweight threads für kooperatives Multitasking über einen einzelnen Thread sein sollen verwendet werden, haben sie billig Kontext zu regelmäßigen Vergleich Fäden Switching- und sie vereinfachen die Programmierung. Eine Beispielverwendung ist ein System mit mehreren Threads, die jeweils mehrere Fasern haben, die eine Art Arbeitshierarchie auf ihrem Eltern-Thread ausführen (niemals den Eltern-Thread verlassend).

Obwohl es nicht die beabsichtigte Verwendung ist, möchte ich noch lernen, wie man es macht, wenn es allgemein möglich ist, weil ich denke, dass ich die Arbeitslast auf meinem Jobsystem durch Migrieren von Fasern zwischen Threads optimieren kann.

+2

Zumindest für Windows-Fasern ist die Antwort "Ja". Aus [der Dokumentation zu 'SwitchToFiber'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686350.aspx):" Sie können 'SwitchToFiber' mit der Adresse einer Faser aufrufen, die von erstellt wurde ein anderer Thread. " –

+0

Ich glaube nicht, dass es eine generische Antwort geben kann, da "Faser" ein lose definierter Begriff ist. Grundsätzlich erfasst eine Faser den Ausführungszustand von einem Thread. Die Frage ist daher, ob sie den vollen Zustand erfasst. – MSalters

Antwort

1

Die erwähnte boost.fiber verwendet boost.context (callcc/continuation), um den Kontextwechsel zu implementieren. Till boost-1.64 callcc wurde nur in Assembler implementiert, boost-1.65 ermöglicht die Auswahl zwischen Assembler, Windows Fibers (Windows) oder ucontext (POSIX falls verfügbar; veraltetes API von POSIX). Die Assembler-Implementierung ist schneller als die anderen beiden (2 Größenordnungen im Vergleich zu Ucontext).

boost.fiber verwendet callcc, um leichte Threads/Fasern zu implementieren - die Bibliothek bietet Glasfaser-Scheduler, mit denen Fasern zwischen Threads migriert werden können. Zum Beispiel stiehlt ein bereitgestellter Scheduler Fasern von anderen Threads, wenn seine Run-Queue arbeitslos wird (Fasern, die bereit sind/wieder aufgenommen werden können).

(so können Sie Windows-Fasern auswählen, die zwischen Threads migriert werden).

+0

Ihre Antwort ist sehr hilfreich und informativ, aber sie beantwortet meine Frage nicht direkt. Können Sie ein Beispiel für die Verwendung von boost.context (callcc/continuation) hinzufügen, um auf sichere Weise zwischen Threads zu migrieren (keine Stapelbeschädigung beim Bereinigen eines in einem anderen Thread erstellten Kontexts)? – DontCareBear