Windows核心编程学习笔记(23)--纤程

Drecik学习经验分享

转载请注明出处:http://blog.csdn.net/drecik__/article/details/8202023


Windows提供纤程是为了帮助各个公司更快地、正确地将它们的代码从UNIX移植到Windows中。

但我们要记住,自己在Windows上设计程序时,应该避免使用纤程,而使用Windows提供的线程机制。

首先要了解的是,纤程是在用户模式下实现的,内核对纤程一无所知,内核会根据我们定义的算法来对纤程进行调度。

一个线程可以包含一个或多个纤程。对内核而言它会对线程进行抢占式调度来让线程执行代码,但是,线程一次只能执行一个纤程代码(由我们决定哪个纤程)。

使用纤程的步骤:

通过函数ConvertThreadToFiber将一个已有的线程转化为一个纤程:

LPVOID		// 返回纤程执行上下文的地址;
ConvertThreadToFiber(
	LPVOID lpParameter
	);

该函数会创建一个纤程的执行上下文,有下面元素构成:

  • 一个用户自定义的值,即传入的lpParameter参数
  • 结构化异常处理链的头
  • 纤程栈的顶部和底部的内存地址
  • 某些CPU寄存器,其中包括栈指针,指令指针以及其他寄存器
默认情况下CPU浮点状态信息不属于CPU寄存器一部分,不会每个纤程都维护一份,如果纤程需要执行浮点操作,则需要使用函数ConvertThreadToFiberEx来转换:
LPVOID
ConvertThreadToFiberEx(
	LPVOID lpParameter,
	DWORD dwFlags			// 传入FIBER_FLAG_FLOAT_SWITCH标志;
	);

除非打算创建更多的纤程,并让它们在同一个线程中运行,否则没有理由将一个线程转换为纤程,创建另一个纤程,当前线程使用CreateFiber或CreateFiberEx:

LPVOID		// 返回纤程执行上下文的地址;
CreateFiber(
	SIZE_T dwStackSize,			// 栈大小,通常为0;
	LPFIBER_START_ROUTINE lpStartAddress,	// 指定纤程函数的地址;
	LPVOID lpParameter			// 用户自定义值,会保存到纤程执行上下文;
	);

LPVOID
CreateFiberEx(
	SIZE_T dwStackCommitSize,	// 指定一开始要调拨的物理存储页;
	SIZE_T dwStackReserveSize,	// 预定指定数量的虚拟内存;
	DWORD dwFlags,				// 可以指定需要进行浮点操作,传入FIBER_FLAG_FLOAT_SWITCH标志;
	LPFIBER_START_ROUTINE lpStartAddress,
	LPVOID lpParameter
	);

// 纤程函数的函数原型;
// 该函数不应该返回,如果返回,该线程以及它创建的所有纤程都会立即被销毁;
typedef VOID (WINAPI *PFIBER_START_ROUTINE)(
	LPVOID lpFiberParameter		// 传入用户自定义的值;
	);

CreateFiber(Ex)与ConvertTreadToFiber(Ex)不同之处在于,它创建的纤程不会立即执行,因为当前运行的纤程还在执行,在同一时刻只能执行一个纤程,可以使用SwitchToFiber来让新的纤程执行:

VOID
SwitchToFiber(
	LPVOID lpFiber	// 纤程执行上下文地址;
	);

在内部该函数会将正在执行的纤程CPU寄存器保存起来在执行上下文中,然后将要执行纤程的CPU寄存器载入到CPU中,并将新的纤程与线程关联,让线程运行指定的纤程,最后就是载入指令指针,让纤程从上次运行的地方开始执行。

最后可以调用DeleteFiber啦销毁纤程:

VOID
DeleteFiber(
	LPVOID lpFiber	// 纤程执行上下文地址;
	);

函数会删除该参数标识的纤程,并释放线程的栈并销毁纤程的执行上下文,如果该纤程与线程正在关联,则会在内部调用ExitThread,从而使线程以及为它创建的纤程都结束。

DeleteFiber通常为一个纤程调用,以删除另一个纤程,与线程不同,线程是最好不要终止另外一个线程。

当所有纤程都被删除,可以调用ConvertFiberToThread(Ex)来解除线程的纤程状态,同时释放最后一块内存块。

如果想知道当先的线程相关联的纤程地址,可以调用GetCurrentFiber,也可以调用GetFiberData返回用户自定义的值。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值