博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi中纤程的使用
阅读量:4514 次
发布时间:2019-06-08

本文共 2356 字,大约阅读时间需要 7 分钟。

首先我们来看看纤程的定义

  纤程(来自百科):

    纤程是Windows为了将Unix服务程序更好的移植到Windows上而创建的,

    线程是在Windows内核中实现的,纤程是在用户模式下实现的,内核对纤程一无所知,内核会根据我们定义的算法来对纤程进行调度。
    一个线程可以包含一个或多个纤程。多个纤程可以使用单个线程来运行。单个纤程也可以被多个线程运行,但每次只能有一个线程运行它。
    纤程一定要通过线程来关联它。
    
 
Delphi中关于纤程的函数或者WindowsAPI有:            

function CreateFiber(dwStackSize: DWORD;  lpStartAddress: TFNFiberStartRoutine;  lpParameter: Pointer): Pointer;

分配纤程对象,为其分配一个堆栈,并设置执行函数。如果函数成功,则返回值是纤程的地址。如果函数失败,则返回值为nil。

当你使用CreateFiber(Ex)函数创建一个纤程之后,该纤程不会执行,因为系统不会自动调度它。你必须调用函数SwitchToFiber来告诉系统你想要哪个纤程执行。

dwStackSize:堆栈的初始大小,以字节为单位。 如果此参数为零,则新纤程使用可执行文件的默认堆栈大小。

lpStartAddress:指向由纤程执行的应用程序定义函数的指针(纤程要执行的功能函数)。 在另一纤程使用此地址调用SwitchToFiber功能之前,不会开始执行新创建的纤程。

lpParameter:传递给纤程的变量的指针。 纤程可以使用GetFiberData宏检索此数据。

该函数并不能直接运行纤程指定的函数,需要通过 函数 ConvertThreadToFiber 将当前的线程转化为纤程才可使用。

 

 

function ConvertThreadToFiber(lpParameter: Pointer): DWORD; 

  将当前线程转换为纤程。 在调度其他纤程之前,必须将线程转换为纤程。

如果函数成功,则返回值是纤程的地址。如果函数失败,则返回值为nil。

lpParameter:传递给纤程的变量的指针。 纤程可以使用GetFiberData宏检索此数据。

 

  只有纤程才能执行其他纤程。 如果线程需要执行纤程,则必须调用ConvertThreadToFiber或ConvertThreadToFiberEx来创建一个区域来保存纤程状态信息。 线程现在是当前的纤程。 该纤程的状态信息包括lpParameter指定的纤程数据。

       

BOOL WINAPI ConvertFiberToThread(void);

该函数释放ConvertThreadToFiber函数分配的资源。 调用此函数后,您无法从线程调用任何纤程功能。

要编译使用此功能的应用程序,需要Windows Vista 或者 Windows XP;(--------除此之外的系统不能用了 :(   ------------ )

不过我试过貌似可以手动加载这个函数,通过LoadLibrary。

 

先看个例子:

  我们先创建个线程对象,然后在线程中创建纤程,在将线程转为纤程

线程代码:

    

unit ThrdFiber;interfaceuses  Classes,Windows,SysUtils,Dialogs;type  TFiber = class(TThread)  private    {
Private declarations } protected procedure Execute; override; public constructor Create(Suspended:Boolean); end;implementationuses Main;{
TFiber }var hwnd:Pointer; x:Integer; hThread:Cardinal;procedure SetText(P:Pointer);stdcall;var i:Integer;begin for i := PInteger(P)^ downto 1 do begin MainFrm.Caption:=IntToStr(i); end; SwitchToFiber(Pointer(hThread)); //这里切换回1,然后后面释放 2end;constructor TFiber.Create(Suspended: Boolean);begin inherited; FreeOnTerminate:=True;end;procedure TFiber.Execute;begin x:=5000; hThread:=ConvertThreadToFiber(nil); // 纤程 1 hwnd:=CreateFiber(0,@SetText,PInteger(@x)); // 纤程 2 SwitchToFiber(hwnd); //1 切换 2,那么2的释放就得切换回1来释放,如果没有切换回1,则下面的语句不会执行// ShowMessage('没有执行...'); DeleteFiber(hwnd); //后面还可以使用ConvertFiberToThread来结束当前的线程end;end.

暂时只了解这么多....

 

 

 

 

转载于:https://www.cnblogs.com/Coder-MIFir/p/10918402.html

你可能感兴趣的文章
Android中常用的几种加密
查看>>
50.Android编码规范
查看>>
linux下source命令的基本功能
查看>>
linux-IO重定向-文本流重定向
查看>>
MSSQLSERVER服务无法启动的解决方案
查看>>
MySQL数据库管理
查看>>
ASP.NET中进度条的简单应用
查看>>
Java Activiti6.0 spring5 SSM 工作流引擎 审批流程 java项目框架
查看>>
md5
查看>>
Linux下的crontab定时执行任务命令详解
查看>>
C#高级编程(第7版) Professional C# 4 and .NET 4 - 读书笔记
查看>>
ipad4自动下载了ios8的安装包,好几个G啊,不想更新,怎么删了呢?
查看>>
JS中的Navigator 对象
查看>>
Android 开源控件与常用开发框架开发工具类
查看>>
记录一次网站打开卡--排故障过程
查看>>
第四章小结
查看>>
Windows7下python2.7.6环境变量配置
查看>>
java设计模式------代理模式
查看>>
WPF学习笔记----注释标记,使用自定义资源字典(style)文件的流程
查看>>
元素定位的八大法则
查看>>