-概述
为了更容易将已有的UNIX服务器应用迁移到Windows,增加了纤程。
UNIX应用程序的开发人员创建了线程包,来实现类似线程功能。
为了帮助各公司更快,更正确地将代码移植到windows,windows在系统中增加 了纤程。
-使用纤程
线程在windows内核中实现的。
纤程是在用户模式下实现的。
一个线程可包含多个纤程。
1.
将一个已有的线程转换为一个纤程。
PVOID ConvertThreadToFiber(PVOID pvParam);
为纤程的执行上下文分配内存。
执行上下文:
pvParam
结构化异常处理链的头
纤程栈的顶部和底部的内存地址
某些CPU寄存器。
x86系统,CPU的浮点信息,不属于CPU寄存器的一部分。纤程执行浮点操作,用
// 返回纤程的执行上下文的内存地址
PVOID ConvertThreadToFiberEx(
PVOID pvParam,
// FIBER_FLAG_FLOAT_SWITCH
DWORD dwFlags
);
分配+初始化了,纤程的执行上下文后,须将执行上下文的地址与线程关联起来。
除非我们打算创建更多的纤程,并让它们在同一个线程中运行,否则,不必将一个线程转换为纤程。
// 创建另一个纤程,返回纤程执行上下文地址
PVOID CreateFiber(
DWORD dwStackSize,
PFIBER_START_ROUTINE pfnStartAddress,
PVOID pvParam
);
PVOID CreateFiberEx(
// 一开始要调拨的物理存储页
SIZE_T dwStackCommitSize,
// 预定的虚拟内存
SIZE_T dwStackReserveSize,
// FIBER_FLAG_FLOAT_SWITCH 把浮点状态包含到纤程上下文
DWORD dwFlags,
PFIBER_START_ROUTINE pStartAddress,
PVOID pvParam
);
// 如果纤程函数返回,那线程及它创建的所有纤程都将被销毁
VOID WINAPI FiberFunc(PVOID pvParam);
CreateFiber,先试图创建一个栈,大小由dwStackSize决定。默认下,栈大小初始为两个物理存储页,但可增大到1MB。
分配+初始化纤程上下文。
同一线程中,同一时刻,只能执行一个纤程。
// 让指定纤程执行,参数为纤程执行上下文的地址
VOID SwitchToFiber(PVOID pvFiberExecutionContext);
工作:
1.将一些CPU寄存器目前值,保存到当前正在运行的纤程的执行上下文。
2.从即将运行的纤程的执行上下文中,将先前保存的寄存器的值载入CPU寄存器。
3.将新纤程的执行上下文与线程关联,让线程运行指定的纤程。
4.将线程的指令指针设为先前保存的指令指针。
// 销毁纤程
// 释放纤程的栈,销毁纤程的执行上下文
// 如纤程当前正与线程关联,会使线程及纤程都结束
VOID DeleteFiber(PVOID pvFiberExecutionContext);
所有纤程都被删除时,可用ConvertFiberToThread来解除线程的纤程状态。同时,释放将线程转化为纤程所占用的最后一块内存。
如需为每个纤程保存信息,可用纤程句柄存储区。
1.调用FlsAlloc来分配一个FLS槽,进程中所有纤程都可用。
纤程被销毁,FLS槽由于FlsFree被删除时,该回调函数被调用。
2.
FlsSetValue在FLS槽中保存与每个纤程相关的数据。
FlsGetValue来得到数据。
IsThreadAFiber,判断是否正在一个纤程执行上下文运行。
得到当前正运行的纤程的执行上下文地址:
PVOID GetCurrentFiber();
PVOID GetFiberData();