纤维
光纤是必须由应用程序手动安排的执行单元。 光纤在计划它们的线程的上下文中运行。 每个线程可以计划多个光纤。 通常,与设计良好的多线程应用程序不一样,光纤没有优势。 但是,使用光纤可以更轻松地移植设计为计划其自己的线程的应用程序。
从系统的角度来看,由光纤执行的操作被视为由运行它的线程执行。 例如,如果光纤访问 线程本地存储 (TLS) ,则它访问运行它的线程的线程本地存储。 此外,如果光纤调用 ExitThread 函数,则运行它的线程将退出。 但是,光纤并没有与线程关联的相同状态信息。 为光纤维护的唯一状态信息是其堆栈、其寄存器的子集,以及创建光纤期间提供的光纤数据。 保存的寄存器是通常在函数调用中保留的寄存器集。
光纤不是提前安排的。 可以通过从另一个光纤切换到光纤来计划该光纤。 系统仍计划线程运行。 当线程运行光纤被抢占时,其当前正在运行的光纤将被抢占,但仍处于选中状态。 所选的光纤在其线程运行时运行。
在计划第一个光纤之前,请调用 ConvertThreadToFiber 函数来创建一个用于保存光纤状态信息的区域。 调用线程现在是当前正在执行的光纤。 此光纤的存储状态信息包括作为参数传递给 ConvertThreadToFiber 的光纤数据。
CreateFiber 函数用于从现有光纤创建新光纤;调用需要堆栈大小、起始地址和光纤数据。 起始地址通常是用户提供的函数,称为光纤函数,它采用一个参数 (光纤数据) ,并且不返回值。 如果光纤函数返回,则运行光纤的线程将退出。 若要执行使用 CreateFiber 创建的任何光纤,请调用 SwitchToFiber 函数。 可以使用由其他线程创建的光纤的地址调用 SwitchToFiber 。 为此,必须在名为 CreateFiber 的另一个线程时将地址返回到该线程,并且必须使用正确的同步。
光纤可以通过调用 GetFiberData 宏来检索光纤数据。 光纤可以随时通过调用 GetCurrentFiber 宏来检索光纤地址。
光纤本地存储
光纤可以使用 光纤本地存储 (FLS) 为每个光纤创建变量的唯一副本。 如果未发生光纤切换,则 FLS 的行为与 线程本地存储完全相同。 FLS 函数 (FlsAlloc、 FlsFree、 FlsGetValue 和 FlsSetValue) 操作与当前线程关联的 FLS。 如果线程正在执行光纤,并且该光纤已切换,则 FLS 也会切换。
若要清理与光纤关联的数据,请调用 DeleteFiber 函数。 此数据包括堆栈、寄存器的子集和光纤数据。 如果当前运行的光纤调用 DeleteFiber,则其线程将调用 ExitThread 并终止。 但是,如果另一个线程中运行的光纤删除了某个线程的所选纤维,则已删除的光纤的线程可能会异常终止,因为已释放该纤维堆栈。
相关主题