繊維

ファイバーは、アプリケーションによって手動でスケジュールする必要がある実行の単位です。 ファイバーは、それらをスケジュールするスレッドのコンテキストで実行されます。 各スレッドは、複数のファイバーをスケジュールできます。 一般に、ファイバーは、適切に設計されたマルチスレッド アプリケーションよりも利点を提供しません。 ただし、ファイバーを使用すると、独自のスレッドをスケジュールするように設計されたアプリケーションを移植しやすくなります。

システムの観点からは、ファイバーによって実行される操作は、ファイバーを実行するスレッドによって実行されたと見なされます。 たとえば、ファイバーが スレッド ローカル ストレージ (TLS) にアクセスする場合、そのファイバーは、それを実行しているスレッドのスレッド ローカル ストレージにアクセスします。 さらに、ファイバーが ExitThread 関数を呼び出すと、それを実行しているスレッドが終了します。 ただし、ファイバーには、スレッドに関連付けられている状態情報と同じ状態情報がすべて関連付けられているわけではありません。 ファイバーに対して維持される唯一の状態情報は、そのスタック、レジスタのサブセット、およびファイバーの作成時に提供されるファイバー データです。 保存されたレジスタは、通常、関数呼び出し全体で保持されるレジスタのセットです。

ファイバーはプリエンプティブにスケジュールされていません。 別のファイバからファイバに切り替えて、ファイバをスケジュールします。 システムは引き続きスレッドの実行をスケジュールします。 スレッド実行中のファイバーが割り込まれた場合、現在実行中のファイバーは割り込まれますが、選択されたままです。 選択したファイバーは、スレッドの実行時に実行されます。

最初のファイバーをスケジュールする前に、 ConvertThreadToFiber 関数を呼び出して、ファイバー状態情報を保存する領域を作成します。 呼び出し元のスレッドが現在実行中のファイバーになりました。 このファイバーの格納された状態情報には、 ConvertThreadToFiber に引数として渡されるファイバー データが含まれます。

CreateFiber 関数は、既存のファイバーから新しいファイバーを作成するために使用されます。呼び出しには、スタック サイズ、開始アドレス、およびファイバー データが必要です。 開始アドレスは、通常、1 つのパラメーター (ファイバー データ) を受け取り、値を返さない、ファイバー関数と呼ばれるユーザー指定の関数です。 ファイバー関数が戻ると、ファイバーを実行しているスレッドが終了します。 CreateFiber で作成されたファイバーを実行するには、SwitchToFiber 関数を呼び出します。 SwitchToFiber は、別のスレッドによって作成されたファイバーのアドレスで呼び出すことができます。 これを行うには、 CreateFiber を呼び出したときにアドレスが他のスレッドに返され、適切な同期を使用する必要があります。

ファイバーは 、GetFiberData マクロを呼び出すことによってファイバー データを取得できます。 ファイバーは 、GetCurrentFiber マクロを呼び出すことによって、いつでもファイバー アドレスを取得できます。

ファイバー ローカル ストレージ

ファイバーでは、 ファイバー ローカル ストレージ (FLS) を使用して、各ファイバーの変数の一意のコピーを作成できます。 ファイバー切り替えが発生しない場合、FLS は スレッド ローカル ストレージとまったく同じように動作します。 FLS 関数 (FlsAllocFlsFreeFlsGetValueおよび FlsSetValue) は、現在のスレッドに関連付けられている FLS を操作します。 スレッドがファイバーを実行していて、ファイバーが切り替わると、FLS も切り替えられます。

ファイバーに関連付けられているデータをクリーンするには、DeleteFiber 関数を呼び出します。 このデータには、スタック、レジスタのサブセット、およびファイバー データが含まれます。 現在実行中のファイバーが DeleteFiber を呼び出した場合、そのスレッドは ExitThread を呼び出して終了します。 ただし、スレッドの選択したファイバーが別のスレッドで実行されているファイバーによって削除された場合、ファイバー スタックが解放されているため、削除されたファイバーを持つスレッドが異常終了する可能性があります。

ファイバーの使用