进程——线程——纤程

========================================
进程——线程——纤程
========================================
    我们都知道线程,但是对纤程的认识,貌似不是清晰。在网上搜了一下,关于纤程的资源,也不是非常多。
纤程,除了不能被线程自动调度外,和线程基本是一致的。
 
一、PVOID ConvertThreadToFiber(PVOID pvParam);
调用这个函数之后,系统为纤程执行环境分配大概200字节的存储空间
 
二、如果一个线程中只有一个纤程,那么是没有必要将该线程转换为纤程的,只有你打算在同一个线程中再创建一个纤程才有转换的必要:
PVOID CreateFiber(DWORD dwStackSize , PFIBER_START_ROUTINE pfnStartAddress , PVOID pvParam);
我们可以用GetLastError();获取错误信息。
 
三、SwitchToFiber函数内部的执行步骤如下:
1、保存当前的CPU寄存器信息,这些信息保存在正在运行的纤程的执行环境中。
2、从将要执行的纤程的执行环境中加载上次保存的CPU寄存器信息。
3、将即将执行的纤程执行环境与线程关联起来,由线程执行指定的纤程。
4、将指令指针设置为保存的值,继续上次的执行。
 
四、DeleteFiber函数一般是由一个纤程调用来删除另一个纤程。


DeleteFiber函数原型:
VOID WINAPI DeleteFiber( LPVOID lpfiber)
//其中lpfiber:需要删除的Fiber地址;


当所有纤程结束了运行,你若需要从纤程转换为线程,则呼叫ConvertFiberToThread函数。
你若想知道你是否正在一个纤程执行环境中运行,可以使用IsThreadAFiber函数,它返回一个BOOL值,指明你是否正在一个纤程中运行。
 
五、一个线程每次只能执行一个纤程,该纤程与这个线程相关联。
1、你可以使用如下函数来得到正在执行的纤程的执行环境内存地址,返回当前纤程的指针:
PVOID GetCurrentFiber();其实这是个宏
2、通过下函数获取当前纤程数据的指针:
GetFiberData();也是个宏
 
六、最后,让我们假设一个线程中有2个纤程,总结一下纤程的用法:
1、使用ConverThreadToFiber(Ex)将当前线程转换到纤程,这是纤程F1
2、定义一个纤程函数,用于创建一个新纤程:VOID CALLBACK FiberProc();
3、纤程F1中调用CreateFiber(Ex)函数创建一个新的纤程F2
4、SwitchToFiber函数进行纤程切换,让新创建的纤程F2执行
5、F2纤程函数执行完毕的时候,使用SwitchToFiber转换到F1
6、在纤程F1中调用DeleteFiber来删除纤程F2
7、纤程F1中调用ConverFiberToThread,转换为线程
8、线程结束
 
七、关于线程
1、AfxBeginThread() , _beginthread() , CWinThread::CreateThread() 的实现都利用了Win32 API函数CreateThread()
2、CreateThread() 和 _beginthread() 相比:
若一个线程调用了C运行时函数库,最好用 _beginthread() 和 _endthread() 来管理线程,而不要用 CreateThread() 和 ExitThread() ,否则在用 ExitThread() 时会造成少量内存泄露。
3、MFC中将线程的管理进行了封装,
在MFC中,被应用的程序框架用来维护线程信息的线程局部数据是由 CWinThread类 来维护。
所以啊,一切用MFC类的线程都要通过CWinThread类来创建
而通过 Win32 API 创建多线程比MFC要复杂,但更加灵活。
4、通过 Win32 API 创建线程,是创建多线程最原始的方法,利用 _beginthread() 是使用C运行时库的最佳选择。
MFC对各种线程函数进行了封装,可以创建工作、用户界面线程
5、线程有优先级。
线程优先级 = 所在进程优先级 + 微调优先级
6、纤程是一中轻量级线程。
不同的是,纤程的调度不是抢占式的,纤程之间的转换完全由应用程序自己控制。

你可能感兴趣的:(Windows_C#)