DELPHI纤程的演示
DELPHI纤程的演示
DELPHI7编译运行通过。
纤程实现单元:
unit FiberFun;
//Fiber(纤程测试Demo)
//2018/04/11
//QQ: 287413288
//参考 https://www.cnblogs.com/lanuage/p/7725683.html
interface
uses Windows,Messages,classes,SysUtils,ComObj;
type
TFiber=class(TThread)
private
FMainHandle:HWnd;
FData:string;
FWorkDone:Boolean;
procedure WriteLog(const Value:string);
protected
hFiberMain:Pointer;
hFiberA:Pointer;
hFiberB:Pointer;
procedure Execute();override;
public
constructor Create();
public
property WorkDone:Boolean Read FWorkDone;
property MainWndHandle:HWnd read FMainHandle write FMainHandle;//主窗体句柄
end;
const
WM_WRITE_LOG = WM_USER + 1;
implementation
const
kernel32 = 'kernel32.dll';
/// <summary>
/// 在主纤程中调用CreateFiber函数创建子纤程
/// D7自带的 CreateFiber()声明有错误
/// </summary>
/// <param name="dwStackSize"></param>
/// <param name="lpStartAddress"></param>
/// <param name="lpParameter"></param>
/// <returns></returns>
function CreateFiber(dwStackSize: DWORD; lpStartAddress: TFNFiberStartRoutine;
lpParameter: Pointer): Pointer; stdcall;external kernel32;
/// <summary>
/// 将一个线程转化为纤程(或者说将一个线程与纤程绑定,以后可以将该纤程看做主纤程)
/// </summary>
/// <param name="lpParameter">这个函数传入一个参数,类似于CreateThread函数中的线程函数参数,如果我们在主纤程中需要使用到它,可以使用宏GetFiberData取得这个参数。 </param>
/// <returns></returns>
function ConvertThreadToFiber(lpParameter:Pointer):Pointer; stdcall;external kernel32; // fiber data for new fiber);
//BOOL ConvertFiberToThread(VOID);
/// <summary>
/// 将一个纤程转化为线程
/// </summary>
/// <returns></returns>
function ConvertFiberToThread():BOOL;stdcall;external kernel32;
/// <summary>
/// 子纤程A的处理函数
/// </summary>
/// <param name="lpParameter"></param>
procedure FiberProcA(lpParameter:Pointer);stdcall;
var
Index:Integer;
Obj:TFiber;
begin
Obj := TFiber(lpParameter);
Assert(Obj <> nil,'FiberProcA;lpParameter=nil');
Obj.WriteLog(format('FiberProcA;ThreadId=%d;[BEGIN]',[GetCurrentThreadId]));
for Index := 1 to 20 do
begin
Obj.WriteLog(format('FiberProcA;ThreadId=%d;Index=%d',[GetCurrentThreadId,Index]));
Obj.FData := ComObj.CreateClassID();
SwitchToFiber(Obj.hFiberB);
Sleep(50);
end;
obj.Terminate();
SwitchToFiber(Obj.hFiberB);
Obj.WriteLog(format('FiberProcA;ThreadId=%d;[END]',[GetCurrentThreadId]));
SwitchToFiber(Obj.hFiberMain);
end;
/// <summary>
/// 子纤程B的处理函数
/// </summary>
/// <param name="lpParameter"></param>
procedure FiberProcB(lpParameter:Pointer);stdcall;
var
Obj:TFiber;
begin
Obj := TFiber(lpParameter);
Assert(Obj <> nil,'FiberProcB;lpParameter=nil');
Obj.WriteLog(format('FiberProcB;ThreadId=%d;[BEGIN]',[GetCurrentThreadId]));
while(not obj.Terminated) do
begin
Obj.WriteLog(format('FiberProcB;ThreadId=%d;Data=%s',[GetCurrentThreadId,Obj.FData]));
//Sleep(10);
SwitchToFiber(Obj.hFiberA);
end;
Obj.WriteLog(format('FiberProcB;ThreadId=%d;[END]',[GetCurrentThreadId]));
SwitchToFiber(Obj.hFiberA);
end;
{ TFiber }
constructor TFiber.Create;
begin
inherited Create(TRUE);
FWorkDone := FALSE;
end;
procedure TFiber.Execute;
begin
FWorkDone := FALSE;
WriteLog(format('TFiberThread;[BEGIN];ThreadId=%d',[GetCurrentThreadId]));
// 转换到纤程
hFiberMain := ConvertThreadToFiber(nil);
if hFiberMain = nil then
raise Exception.CreateFmt('ConvertThreadToFiber Failure LastErrorCode=%d',[GetLastError()]);
// 创建子纤程A
hFiberA :=CreateFiber(1024,Pointer(@FiberProcA),Pointer(Self));
if hFiberA = nil then
raise Exception.CreateFmt('CreateFiber Failure LastErrorCode=%d',[GetLastError()]);
// 创建子纤程B
hFiberB :=CreateFiber(1024,Pointer(@FiberProcB),Pointer(Self));
if hFiberB = nil then
raise Exception.CreateFmt('CreateFiber Failure LastErrorCode=%d',[GetLastError()]);
// 切换到纤程A
SwitchToFiber(hFiberA);
// 删除纤程
DeleteFiber(hFiberA);
DeleteFiber(hFiberB);
// 变回线程
ConvertFiberToThread();
WriteLog(format('TFiberThread;[END];ThreadId=%d',[GetCurrentThreadId]));
FWorkDone := TRUE;
end;
procedure TFiber.WriteLog(const Value: string);
var
Msg:string;
begin
Msg := formatDateTime('YYYY-MM-DD hh:mm:ss.zzz',Now) + ':' + Value;
SendMessage(MainWndHandle,WM_WRITE_LOG,WPARAM(Msg),0);
end;
end.
调用:
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,StdCtrls, ExtCtrls, ComCtrls,FiberFun;
type
TfrmMain = class(TForm)
StatusBar1: TStatusBar;
Panel1: TPanel;
mmLog: TMemo;
btnStartFiber: TButton;
procedure btnStartFiberClick(Sender: TObject);
private
{ Private declarations }
protected
procedure WndProc(var MsgRec:TMessage);override;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.btnStartFiberClick(Sender: TObject);
var
Obj:TFiber;
begin
btnStartFiber.Enabled := FALSE;
mmLog.Clear();
Obj := TFiber.Create();
Obj.MainWndHandle := Self.Handle;
Obj.FreeOnTerminate := FALSE;
Obj.Resume();
while(not Obj.WorkDone) do
begin
Application.ProcessMessages();
Sleep(10);
end;
Obj.Free();
btnStartFiber.Enabled := TRUE;
end;
procedure TfrmMain.WndProc(var MsgRec: TMessage);
begin
if MsgRec.Msg = WM_WRITE_LOG then
begin
mmLog.Lines.Add(string(MsgRec.WParam));
end
else
inherited;
end;
end.
DELPHI纤程的演示的更多相关文章
- 第12章 纤程(Fiber)
12.1 纤程对象的介绍 (1)纤程与线程的比较 比较 线程(Thread) 纤程(Fiber) 实现方式 是个内核对象 在用户模式中实现的一种轻量级的线程,是比线程更小的调度单位. 调度方式 由Mi ...
- 基于纤程(Fiber)实现C++异步编程库(一):原理及示例
纤程(Fiber)和协程(coroutine)是差不多的概念,也叫做用户级线程或者轻线程之类的.Windows系统提供了一组API用户创建和使用纤程,本文中的库就是基于这组API实现的,所以无法跨平台 ...
- windows 纤程
纤程本质上也是线程,是多任务系统的一部分,纤程为一个线程准并行方式调用多个不同函数提供了一种可能,它本身可以作为一种轻量级的线程使用.它与线程在本质上没有区别,它也有上下文环境,纤程的上下文环境也是一 ...
- Java 中的纤程库 – Quasar
来源:鸟窝, colobu.com/2016/07/14/Java-Fiber-Quasar/ 如有好文章投稿,请点击 → 这里了解详情 最近遇到的一个问题大概是微服务架构中经常会遇到的一个问题: 服 ...
- Windows核心编程:第12章 纤程
Github https://github.com/gongluck/Windows-Core-Program.git //第12章 纤程.cpp: 定义应用程序的入口点. // #include & ...
- nodejs中的fiber(纤程)库详解
fiber/纤程 在操作系统中,除了进程和线程外,还有一种较少应用的纤程(fiber,也叫协程).纤程常常拿来跟线程做对比,对于操作系统而言,它们都是较轻量级的运行态.通常认为纤程比线程更为轻量,开销 ...
- 纤程与Quasar
Java使用的是系统级线程,也就是说,每次调用new Thread(....).run(),都会在系统层面建立一个新的线程,然鹅新建线程的开销是很大的(每个线程默认情况下会占用1MB的内存空间,当然你 ...
- 纤程(FIBER)
Indy 10 还包含对纤程的支持.纤程是什么?简单来说,它也是 一个“线程”,但是它是由代码控制的,而不是由操作系统控制的.实际上,可以认为线程 是一个高级纤程.纤程和 Unix 用户线程(Unix ...
- 继续了解Java的纤程库 – Quasar
前一篇文章Java中的纤程库 – Quasar中我做了简单的介绍,现在进一步介绍这个纤程库. Quasar还没有得到广泛的应用,搜寻整个github也就pinterest/quasar-thrift这 ...
随机推荐
- scrollreveal(页面滚动显示动画插件支持手机)
scrollreveal.js是一款可以轻易实现桌面和移动浏览器元素随页面滚动产生动画的js插件.该插件通过配置可以在页面滚动,元素进入视口时产生炫酷的动画效果,同时还支持元素的3D效果,非常的实用. ...
- StringBuilder基本用法
//StringBuilder用法 public class StringBuilderTest { public static void main(String[] args) { StringBu ...
- hdu 3573(数学+贪心)
Buy Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Windows内核分析——内核调试机制的实现(NtCreateDebugObject、DbgkpPostFakeProcessCreateMessages、DbgkpPostFakeThreadMessages分析)
本文主要分析内核中与调试相关的几个内核函数. 首先是NtCreateDebugObject函数,用于创建一个内核调试对象,分析程序可知,其实只是一层对ObCreateObject的封装,并初始化一些结 ...
- wordpress后台加载速度异常缓慢排查记录(原创)
原因在于在function.php函数中加入了下面的代码导致了缓慢: //停用版本更新通知remove_action('load-update-core.php', 'wp_update_themes ...
- 【洛谷】P4585 [FJOI2015]火星商店问题
题解 题目太丧,OJ太没有良心,我永远喜欢LOJ! (TLE报成RE,垃圾洛谷,我永远喜欢LOJ) 好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解 把所有限制去掉,给出一个值, ...
- 安装deb包解决依赖问题
在使用 dpkg -i 安装deb包后,会出现依赖关系而不能正常安装软件,这个时候先更新下源然后解决依赖关系后重装即可. sudo apt-get update # 更新 sudo apt-get - ...
- 在CentOS7命令行模式下安装虚拟机
转载:https://blog.csdn.net/sunnyfg/article/details/51493602 1.主机环境描述: 操作系统:CentOS7 系统GUI:无 CPU:Intel4代 ...
- 9 行 javascript 代码获取 QQ 群成员
昨天看到一条微博:「22 行 JavaScript 代码实现 QQ 群成员提取器」. 本着好奇心点击进去,发现没有达到效果,一是 QQ 版本升级了,二是博客里面的代码也有些繁琐. 于是自己试着写了一个 ...
- cpp笔记(长期更新)
c++0x:c++11标准成为正式标准之前的草案临时名字 多态:接口的多种不同的实现方式即为多态,即子类类型的指针赋值给父类类型的指针 动态内存(堆)的管理是通过一对运算符来完成的: new:在动态内 ...