纤维

光纤是必须由应用程序手动安排的执行单元。 光纤在计划它们的线程的上下文中运行。 每个线程可以计划多个光纤。 通常,与设计良好的多线程应用程序不一样,光纤没有优势。 但是,使用光纤可以更轻松地移植设计为计划其自己的线程的应用程序。

从系统的角度来看,由光纤执行的操作被视为由运行它的线程执行。 例如,如果光纤访问 线程本地存储 (TLS) ,则它访问运行它的线程的线程本地存储。 此外,如果光纤调用 ExitThread 函数,则运行它的线程将退出。 但是,光纤并没有与线程关联的相同状态信息。 为光纤维护的唯一状态信息是其堆栈、其寄存器的子集,以及创建光纤期间提供的光纤数据。 保存的寄存器是通常在函数调用中保留的寄存器集。

光纤不是提前安排的。 可以通过从另一个光纤切换到光纤来计划该光纤。 系统仍计划线程运行。 当线程运行光纤被抢占时,其当前正在运行的光纤将被抢占,但仍处于选中状态。 所选的光纤在其线程运行时运行。

在计划第一个光纤之前,请调用 ConvertThreadToFiber 函数来创建一个用于保存光纤状态信息的区域。 调用线程现在是当前正在执行的光纤。 此光纤的存储状态信息包括作为参数传递给 ConvertThreadToFiber 的光纤数据。

CreateFiber 函数用于从现有光纤创建新光纤;调用需要堆栈大小、起始地址和光纤数据。 起始地址通常是用户提供的函数,称为光纤函数,它采用一个参数 (光纤数据) ,并且不返回值。 如果光纤函数返回,则运行光纤的线程将退出。 若要执行使用 CreateFiber 创建的任何光纤,请调用 SwitchToFiber 函数。 可以使用由其他线程创建的光纤的地址调用 SwitchToFiber 。 为此,必须在名为 CreateFiber 的另一个线程时将地址返回到该线程,并且必须使用正确的同步。

光纤可以通过调用 GetFiberData 宏来检索光纤数据。 光纤可以随时通过调用 GetCurrentFiber 宏来检索光纤地址。

光纤本地存储

光纤可以使用 光纤本地存储 (FLS) 为每个光纤创建变量的唯一副本。 如果未发生光纤切换,则 FLS 的行为与 线程本地存储完全相同。 FLS 函数 (FlsAllocFlsFreeFlsGetValueFlsSetValue) 操作与当前线程关联的 FLS。 如果线程正在执行光纤,并且该光纤已切换,则 FLS 也会切换。

若要清理与光纤关联的数据,请调用 DeleteFiber 函数。 此数据包括堆栈、寄存器的子集和光纤数据。 如果当前运行的光纤调用 DeleteFiber,则其线程将调用 ExitThread 并终止。 但是,如果另一个线程中运行的光纤删除了某个线程的所选纤维,则已删除的光纤的线程可能会异常终止,因为已释放该纤维堆栈。

使用光纤