delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行
unit uJooThread;interfaceuses Classes, uFooThread;type TJooThread = class(TFooThread) public procedure Synchronize(AProc: TThreadMethod); end;implementation{ TJooThread }procedure TJooThread.Synchronize(AProc: TThreadMethod);begin ExecProcInThread(AProc); // 再设计一个等待 AProc 执行结果功能。end;end.unit uJooThread;interfaceuses Classes, SyncObjs, uFooThread, uFooList;type PSyncRec = ^TSyncRec; TSyncRec = record Method: TThreadMethod; // 这是类的方法 Proc: TThreadProcedure; // 这是匿名方法 // 本例只写了类的方法。需要匿名方法,请自行重载 Sync 与 Queue Signle: TEvent; Queue: boolean; end; TSyncRecList = class(TFooList<PSyncRec>) //用于装执行代码的 List protected procedure FreeItem(Item: PSyncRec); override; end; TJooThread = class(TFooThread) private FSyncRecList: TSyncRecList; procedure Check; public constructor Create(ACanAccessCom: boolean); destructor Destroy; override; procedure Synchronize(AProc: TThreadMethod); // 阻塞到 AProc执行完毕才返回。 procedure Queue(AProc: TThreadMethod); // 塞入线程后立即返回。 end; // 本例就是前面单节讲的知识的综合运用。 // TEvent,FooThread,FooList,全都用上了。 // 并构建了一个新的线程功能。 // 当我写完以后发现,与系统源码中, // 窗口接收 WM_NULL 消息后的处理UI操作的功能,几乎是一模一样的。 // 不同的是,本例是在线程时空,系统源码是在主线程时空。implementation{ TJooThread }procedure TJooThread.Check;var p: PSyncRec;begin FSyncRecList.Lock; // 所有要执行的代码,都在这个 List 中了。 // 此处是线程时空,故从List 中取出并执行代码即可。 try p := nil; if FSyncRecList.Count > 0 then // 每次取 List 的第一个来执行。 begin p := FSyncRecList[0]; FSyncRecList.Delete(0); end; finally FSyncRecList.Unlock; end; if Assigned(p) then begin if Assigned(p.Method) then p.Method else if Assigned(p.Proc) then p.Proc(); if not p.Queue then // 如果是阻塞,就置信号。 p.Signle.SetEvent; Dispose(p); ExecProcInThread(Check); end;end;constructor TJooThread.Create(ACanAccessCom: boolean);begin inherited; FSyncRecList := TSyncRecList.Create;end;destructor TJooThread.Destroy;begin FSyncRecList.Free; inherited;end;procedure TJooThread.Queue(AProc: TThreadMethod);var p: PSyncRec;begin FSyncRecList.Lock; try new(p); FSyncRecList.Add(p); p.Method := AProc; p.Queue := true; ExecProcInThread(Check); finally FSyncRecList.Unlock; end;end;procedure TJooThread.Synchronize(AProc: TThreadMethod);var p: PSyncRec; o: TEvent;begin FSyncRecList.Lock; try new(p); FSyncRecList.Add(p); p.Method := AProc; o := TEvent.Create(nil, true, false, ''); p.Signle := o; p.Queue := false; ExecProcInThread(Check); //触发线程启动 finally FSyncRecList.Unlock; end; o.WaitFor; // 等待 AProc 执行完毕的信号 o.Free;end;{ TSyncRecList }procedure TSyncRecList.FreeItem(Item: PSyncRec);begin inherited; if Assigned(Item.Signle) then Item.Signle.Free; Dispose(Item);end;end.delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行的更多相关文章
- delphi 线程教学第五节:多个线程同时执行相同的任务
第五节:多个线程同时执行相同的任务 1.锁 设,有一个房间 X ,X为全局变量,它有两个函数 X.Lock 与 X.UnLock; 有如下代码: X.Lock; 访问资源 P; ...
- delphi 线程教学第四节:多线程类的改进
第四节:多线程类的改进 1.需要改进的地方 a) 让线程类结束时不自动释放,以便符合 delphi 的用法.即 FreeOnTerminate:=false; b) 改造 Create 的参数 ...
- delphi 线程教学第六节:TList与泛型
第六节: TList 与泛型 TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本) ...
- delphi 线程教学第二节:在线程时空中操作界面(UI)
第二节:在线程时空中操作界面(UI) 1.为什么要用 TThread ? TThread 基于操作系统的线程函数封装,隐藏了诸多繁琐的细节. 适合于大部分情况多线程任务的实现.这个理由足够了吧 ...
- delphi 线程教学第一节:初识多线程
第一节:初识多线程 1.为什么要学习多线程编程? 多线程(多个线程同时运行)编程,亦可称之为异步编程. 有了多线程,主界面才不会因为耗时代码而造成“假死“状态. 有了多线程,才能使多个任务同时 ...
- delphi 线程教学第三节:设计一个有生命力的工作线程
第三节:设计一个有生命力的工作线程 创建一个线程,用完即扔.相信很多初学者都曾这样使用过. 频繁创建释放线程,会浪费大量资源的,不科学. 1.如何让多线程能多次被复用? 关键是不让代码退出 ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节
第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...
- 基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...
随机推荐
- hdu-2639 Bone Collector II---第k大背包
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意: 求第k大背包. 思路: 由01背包递推式dp[i][j] = max(dp[i][ ...
- 简述SharePoint designer 工作流实现用户撤回申请得解决方案,how to revoke/recall application in SharePoint designer workflow
在工作中很容易碰到用户提出,需要可以撤回申请得需求.有这么几种实现方法. 方案一:designer中加一个parallel(平行)得anction, 然后在里面添加两个平行运行得审批 第一个是给真正得 ...
- 关于ECMAScript 2016, 2017, 和2018中新增功能(摘抄)
ECMAScript 2016 1. Array.prototype.includes includes是数组上的简单实例方法,并有助于轻松查找某个项是否在Array中(包括NaN不像indexOf) ...
- Java 线程池原理分析
1.简介 线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销.在应用上,线程池可应用在后端相关服务中.比如 Web 服务器,数据库服务器等 ...
- [Awson原创]修水渠(canal)
Description Awson是某国际学校信竞组的一只菜鸡.他们班主任F老师喜欢带他们去爬爬唷喽山.登顶后,Awson有了个奇怪的发现. 山腰上有N(1<=N<=100)个村庄,这些村 ...
- [HNOI 2006]鬼谷子的钱袋
Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一 ...
- 【Codeforces Round 431 (Div. 2) A B C D E五个题】
先给出比赛地址啦,感觉这场比赛思维考察非常灵活而美妙. A. Odds and Ends ·述大意: 输入n(n<=100)表示长度为n的序列,接下来输入这个序列.询问是否可以将序列划 ...
- [BZOJ]3672 购票(Noi2014)
革命尚未成功,同志还需努力. Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ ...
- Python3 中 random模块
Python中的random模块用于生成随机数. 下面具体介绍random模块的功能: 1.random.random() #用于生成一个0到1的 随机浮点数:0<= n < 1.0 im ...
- mysql 及 posgresql之优劣势大比拼
特性 MySQL PostgreSQL 实例 通过执行 MySQL 命令(mysqld)启动实例.一个实例可以管理一个或多个数据库.一台服务器可以运行多个 mysqld 实例.一个实例管理器可以监视 ...