• Delphi中纤程的使用


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

      纤程(来自百科):

        纤程是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;
    
    interface
    
    uses
      Classes,Windows,SysUtils,Dialogs;
    
    type
      TFiber = class(TThread)
      private
        { Private declarations }
      protected
        procedure Execute; override;
      public
        constructor Create(Suspended:Boolean);
      end;
    
    implementation
    
    uses 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,然后后面释放 2
    end;
    
    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.

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

     

  • 相关阅读:
    python实现压缩文件成zip格式
    python实现自动发送邮件
    jmeter业务建模中遇到的问题
    python开发环境必备之vim配置
    第五章 python中的异常处理
    第四章 python中的面向对象设计
    第三章 python中的字符串
    Web前端面试题目及答案汇总
    做一个网站一般的步骤流程有哪些
    不用新变量直接交换现有两个变量的值
  • 原文地址:https://www.cnblogs.com/Master-Qi/p/10918402.html
Copyright © 2020-2023  润新知