当前位置: 首页 > 编程日记 > 正文

Delphi多线程编程中的技巧

1)创建线程 
MsgThread := TMsgThread.Create(False) ; //创建并执行线程 
MsgThread := TMsgThread.Create(True) ; //创建线程后挂起 
constructor Create(CreateSuspended: Boolean); 中的参数CreateSuspended表示创建后是否挂起线程。 
(2)设置线程里没有设置循环执行的话,且设置FreeOnTerminate为True,则线程执行完后就会自己释放。 
(3)在一个线程结束后,调用另一个事件的方法: 
只要设置Onterminate:=某方法,这样在线程结束前自然会被调用,比如 : 
procedure TSendShortMessageThread.Execute; 
var 
Bitmap: Tbitamp; 
begin 
Bimap:=Tbitmap.create(nil) ; 
OnTerminate:=Threaddone; 
end; 

procedure Threaddone(sender: tobject); 
begin 
Bimap.Free; //在Destory之前会被调用 
end; 
(4)程序结束前安全的退出线程的方法: 
if MsgThread <> nil then 
begin 
MsgThread.Terminate ; 
MsgThread.WaitFor ; 
end; 
(5)判断当前线程的状态: 
//以下资料来自大富翁论坛。 
/判断线程是否释放 
//返回值:0-已释放;1-正在运行;2-已终止但未释放; 
//3-未建立或不存在 
function TFrmMain.CheckThreadFreed(aThread: TThread): Byte; 
var 
i: DWord; 
IsQuit: Boolean; 
begin 
if Assigned(aThread) then 
begin 
IsQuit := GetExitCodeThread(aThread.Handle, i); 
if IsQuit then //If the function succeeds, the return value is nonzero. 
//If the function fails, the return value is zero. 
begin 
if i = STILL_ACTIVE then //If the specified thread has not terminated, 
//the termination status returned is STILL_ACTIVE. 
Result := 1 
else 
Result := 2; //aThread未Free,因为Tthread.Destroy中有执行语句 
end 
else 
Result := 0; //可以用GetLastError取得错误代码 
end 
else 
Result := 3; 
end; 
(6)线程同步。 
如果线程要调用VCL里面的内容(如:别的窗体中的控件),就需要将这个线程同步。线程同步表示交由主线程运行这段代码,各个线程都在主线程中分时间段运行。另外,要想避免多个线程同时执行同一段代码也需要将多线程同步。 
临界区和互斥的作用类似,都是用来进行同步的,但它们间有以下一点差别: 
临界区只能在进程内使用,也就是说只能是进程内的线程间的同步;而互斥则还可用在进程之间的;临界区所花消的时间很少,才10~15个时间片,而互斥需要400多个;临界区随着进程的终止而终止,而互斥,如果你不用closehandle()的话,在进程终止后仍然在系统内存在,也就是说它是系统全局对象; 
同步的方法有: 

(1)使用临界区对象。 
临界区对象有两种:TRTLCriticalSection 和 CriticalSection。 
?? TRTLCriticalSection的用法 

var 
GlobalVariable:Double; 

var 
CriticalSection:TRTLCriticalSection; 

procedure SetGlobalVariable(Value:Double); 
begin 
EnterCriticalSection(CriticalSection); //进入临界区 
try 
GlobalVariable:=Value; 
finally 
LeaveCriticalSection(CriticalSection); //离开临界区 
end; 
end; 

initialization 
InitializeCriticalSection(CriticalSection); //初始化 
finalization 
DeleteCriticalSection(CriticalSection); //删除 
end. 
?? CriticalSection(重要区段)的用法: 
var criticalsection: TCriticalsection; 
创建:criticalsection := TCriticalsection.create; 
使用: 
criticalsection.enter; 
try 
... 
finally 
criticalsection.leave; 
end; 

(2)使用互斥 
先在主线程中创建事件对象: 
var 
hMutex: THandle = 0; 
... 
hMutex := CreateMutex(nil, False, nil); 

在线程的Execute方法中加入以下代码: 
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then 
//Do Something; 
... 
ReleaseMutex(hMutex); 

最后记得要释放互斥对象: 
CloseHandle(hMutex); 

(3)使用信号量 

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 
= class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    
procedure FormCreate(Sender: TObject);
    
procedure FormDestroy(Sender: TObject);
    
procedure Button1Click(Sender: TObject);
  
private
    
{ Private declarations }
  
public
    
{ Public declarations }
  
end;

type
  TMyThread 
= class(TThread)
  
private

  
protected
    
procedure Execute; override;
  
public

    
constructor Create; virtual;
  
end;

var
  Form1: TForm1;
  HSem: THandle 
= 0;

implementation

{$R *.dfm}

var
  tick: Integer 
= 0;

procedure TMyThread.Execute;
var
  WaitReturn: DWord;
begin
  WaitReturn :
= WaitForSingleObject(HSem, INFINITE);
  Form1.Edit1.Text :
= IntToStr(tick);
  Inc(tick);
  Sleep(
10);
  ReleaseSemaphore(HSem, 
1, Nil)
end;

constructor TMyThread.Create;
begin
  
inherited Create(False);
  FreeOnTerminate :
= True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  HSem :
= CreateSemaphore(Nil, 11, Nil);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(HSem);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  index: Integer;
begin
  
for index := 0 to 10 do
  
begin
    TMyThread.Create;
  
end;
end;

end.

一般的同步对象使用Mutex对象,是因为Mutex有一个特别之处:当一个持有对象的线程DOWN掉的时候,mutex对象可以自动让其它等待这个对象的线程接受,而其它的内核对象则不具体这个功能。 
之所要使用Semaphore则是因为Semaphore可以提供一个活动线程的上限,即lMaximumCount参数,这才是它的真正有用之处。 

转载于:https://www.cnblogs.com/rogee/archive/2010/09/20/1832057.html

相关文章:

Ubuntu14.04下配置OpenGL及测试代码

ubuntu14.04 64位下&#xff0c;默认是没有安装OpenGL相关依赖库的&#xff0c;若安装&#xff0c;则依次执行如下几条命令即可&#xff1a; $ sudo apt-get update $ sudo apt-get install build-essential $ sudo apt-get install libgl1-mesa-dev $ sudo apt-get install li…

VarGFaceNet:地平线提出轻量级、有效可变组卷积的人脸识别网络

作者 | Mengjia Yan、Mengao Zhao、Zining Xu、Qian Zhang、Guoli Wang、Zhizhong Su译者 | 刘畅编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】为了提高用于人脸识别的轻量级网络的判别和泛化能力&#xff0c;本文提出了一种有效的可…

【TortoiseSVN使用教程】

TortoiseSVN使用教程 TortoiseSVN是一个SVN的客户端 1.Checkout Repository 首 先要Checkout服务器端的Repository&#xff0c;所谓的Checkout就是指获得服务器端指定的Repository。存储的所有文件这个 Checkout和Visual Source Safe的Checkout意义完全不一样&#xff0…

[ASP.NET MVC 小牛之路]10 - Controller 和 Action (2)

继上一篇文章之后&#xff0c;本文将介绍 Controller 和 Action 的一些较高级特性&#xff0c;包括 Controller Factory、Action Invoker 和异步 Controller 等内容。 本文目录 开篇&#xff1a;示例准备 文章开始之前&#xff0c;我们先来了解一下一个请求的发出到Action方法处…

Linux下遍历指定目录的C++实现

之前在 https://blog.csdn.net/fengbingchun/article/details/51474728 给出了在Windows遍历指定文件夹的C实现&#xff0c;这里给出在Linux下遍历目录的实现&#xff0c;Windows和Linux下的实现都是参考了OpenCV 2.x中的实现&#xff0c;OpenCV中的用法可参考https://blog.csd…

要活102年,阿里凭借的是什么?

由浅到深、由轻到重、由拥抱到创新&#xff0c;看似“风平浪静”的历史背后&#xff0c;中国互联网江湖的发展实则“波涛汹涌”。对于身处核心位置的科技巨头阿里巴巴而言&#xff0c;将如何更好地去实现“希望活 102 年”的愿景&#xff1f;凭借的究竟又是什么&#xff1f;作者…

Go基础知识学习(6) 接口

2019独角兽企业重金招聘Python工程师标准>>> Golang接口定义使用interface来声明&#xff0c;它相对于其他语言最大的特定就是接口定义和实现的关联性仅仅依赖接口的名字和声明&#xff0c;无需显式声明。 接口定义和实现 在下面这个例子中&#xff0c;定义了两个自…

多模态数据+知识图谱,这次你的疑难杂症有解了!

数据是AI的基础&#xff0c;不同行业领域的数据来源广泛、形式多样&#xff0c;其每一种来源或形式都可以看作是一种模态&#xff0c;例如视频、图片、语音以及工业场景下的传感数据&#xff0c;红外、声谱等。多模态数据的语义理解与知识表示让智能体能更深入地感知、理解真实…

Linux下通过gettimeofday函数获取程序段执行时间

在Linux下计算某个程序段执行的时间一般使用gettimeofday函数&#xff0c;此函数的声明在sys/time.h文件中。此函数接收两个结构体参数&#xff0c;分别为timeval、timezone.两个结构体的声明如下&#xff1a;struct timeval {time_t tv_sec; /* seconds */long tv_usec; /* mi…

matlab练习程序(Log Polar变换)

Log Polar就是所谓的极坐标变换&#xff0c;通过变换能将笛卡尔坐标系中的图像映射到极坐标系中。 确切的来说我这里不算是Log Polar&#xff0c;因为Log Polar是将图像从&#xff08;x,y&#xff09;映射到(log(r),theta)&#xff0c;而我是将图像从&#xff08;x,y&#xff0…

SiteMapPath基本用法

1、添加一个网站地图项 Web.sitemap项 2、在 Web.sitemap项的写法如下&#xff1a; <?xml version"1.0" encoding"utf-8"?><siteMap xmlns"http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"><siteMapNode url"defa…

closurescallbacks

引用文章原文地址&#xff1a;&#xff08;声明&#xff1a;文章只为自己总结知识&#xff0c;内容东拼西凑&#xff0c;版权归以下作者所有。&#xff09; 1. Wikipedia: callback(computer science) 2. Implement callback routines in Java By John D. Mitchell, JavaWorld.…

吴恩达老师深度学习视频课笔记:卷积神经网络

计算机视觉&#xff1a;包括图像分类(image classification)、目标检测(object detection)、风格迁移(neural style transfer)等等。边缘检测示例&#xff1a;神经网络的前几层可以检测边缘&#xff0c;然后后面几层可能检测到物体的部分&#xff0c;接下来靠后的一些层可能检测…

COCO 2019挑战赛,旷视研究院拿下三项计算机识别冠军 | ICCV 2019

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;10月27日&#xff0c;两年一度的国际计算机视觉大会ICCV 2019&#xff08;InternationalConference on Computer Vision&#xff09;在韩国首尔开幕。作为ICCV 2019重头戏&#xff0c;COCO 是人工智能领域最具影响力的…

runners学习

runners是由salt-run命令调用的&#xff0c;一般我用的到就是jobs和manage模块。源代码是在./site-packages/salt/runners/下的。当然我们可以自定义runners。先谈谈jobs模块。包含active、lookup_jid、list_job、list_jobs、print_job五种方法。salt-run jobs.active ->返回…

Swift基础 - - 高德地图实践

高德地图开发需要自己到官网http://lbs.amap.com/console/ 注册一个ak&#xff0c;新建一个swift工程&#xff0c;然后在Info.plist中添加一个NSLocationAlwaysUsageDescription或者NSLocationWhenInUseUsageDescription。 高德地图的库以及依赖库加入到项目里面 需要的库如下…

Shell脚本示例代码

1. echo_printf_usage.sh: echo和printf的用法 #! /bin/bash# echo和printf的用法# echo是用于终端打印的基本命令.在默认情况下,echo在每次调用后会添加一个换行符 echo "hello, beijing" echo "$(pwd)" echo $(pwd) # 结果并不是希望得到的,将会输出: $…

「2019嵌入式智能国际大会」 399元超值学生票来啦,帮你豪省2600元!

2019 嵌入式智能国际大会即将来袭&#xff01;购票官网&#xff1a;https://dwz.cn/z1jHouwE物联网是继计算机、互联网和移动通信之后的又一次信息产业的革命性发展&#xff0c;在互联网和移动互联网高速发展的时代&#xff0c;几乎所有行业都有数据联网的需求。无论是国外的科…

ThinkPHP学习笔记之Model操作

2019独角兽企业重金招聘Python工程师标准>>> 1. 3种实例化model模型方法 a) new 命名空间GoodsModel(); b) D([“模型标志Goods”]) (之前版本会实例化自定义model对象&#xff0c;目前都实例化Model基类对象) i. 没有参数实例化一个Model对象、有参数也实例化一…

Ubuntu 14.04 64位上配置JDK操作步骤

1. 从 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下载jdk-8u172-linux-x64.tar.gz; 2. 解压缩&#xff1a; tar -xvzf jdk-8u172-linux-x64.tar.gz 3. 创建/usr/jdk目录&#xff1a; sudo mkdir -p /usr/jdk 4. 将解压缩后的jd…

Swift语言实现代理传值

需求&#xff1a;利用代理实现反响传值&#xff08;以下例子采用点击第二个视图控制器中的按钮来改变第一个视图控制器中的Label的内容&#xff09; 一、创建RootViewController import Foundation import UIKitclass RootViewController:UIViewController,ChangeWordDelegate{…

亚马逊马超:如何使用DGL进行大规模图神经网络训练?

演讲嘉宾 | 马超&#xff08;亚马逊应用科学家&#xff09;整理 | 刘静 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;与传统基于张量&#xff08;Tensor&#xff09;的神经网络相比&#xff0c;图神经网络将图 (Graph) 作为输入&#xff0c;从图结构中学习潜在的知…

Python学习系列(六)(模块)

Python学习系列&#xff08;六&#xff09;(模块) Python学习系列&#xff08;五&#xff09;(文件操作及其字典) 一&#xff0c;模块的基本介绍 1&#xff0c;import引入其他标准模块 标准库&#xff1a;Python标准安装包里的模块。 引入模块的几种方式&#xff1a; i&#xf…

Ubuntu14.04 64位上配置终端显示git分支名称

之前在Ubuntu14.04上在终端上显示git分支名称基本上都使用oh-my-zsh&#xff0c;可以参考 https://blog.csdn.net/fengbingchun/article/details/77803322 &#xff0c;由于限制了权限&#xff0c;使得不能安装oh-my-zsh&#xff0c;显示错误如下&#xff1a;在 https://githu…

创建UITextField对象

//创建UITextField对象 UITextField * tf[[UITextField alloc]init];//设置UITextField的文字颜色tf.textColor[UIColor redColor];//设置UITextField的文本框背景颜色tf.backgroundColor[UIColor grayColor];//设置UITextField的边框的风格tf.borderStyleUITextBorderStyleRou…

non-local神经网络:通过非局部操作解决深度神经网络核心问题

译者 | 李杰出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;回想一下我们熟悉的CNN、RNN。如下图所示&#xff0c;这些神经网络模型都是基于局部区域进行操作&#xff0c;属于local operations。为了获得长距离依赖&#xff0c;也就是图像中非相邻像素点之间的关系&a…

fgets()用法笔记

为了避免缓冲区溢出&#xff0c;从终端读取输入时应当用fgets()代替gets()函数。但是这也将带来一个问题&#xff0c;因为fgets()的调用格式是&#xff1a; fgets (buf, MAX, fp)fgets (buf, MAX, stdin) buf是一个char数组的名称&#xff0c;MAX是字符串的最大长度&#xff0c…

iOS 上常用的两个功能:点击屏幕和return退出隐藏键盘和解决虚拟键盘

原文地址&#xff1a;http://blog.csdn.net/xiaotanyu13/article/details/7711954 iOS上面对键盘的处理很不人性化&#xff0c;所以这些功能都需要自己来实现&#xff0c; 首先是点击return和屏幕隐藏键盘 这个首先引用双子座的博客 http://my.oschina.net/plumsoft/blog/42545…

深度学习可解释性问题如何解决?图灵奖得主Bengio有一个解

作者 | Yoshua Bengio, Tristan Deleu等译者 | 刘畅&#xff0c;编辑 | Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;自 2012 年以来&#xff0c;深度学习的发展有目共睹&#xff0c;今年 3 月&#xff0c;为此做出巨大贡献的 Yoshua Bengio、Yann Lecun和Geo…

zepto打造一款移动端划屏插件

效果图 样式1 样式2 调用 正常情况下应该是后台生成的html代码&#xff0c;但还是写了一套操作tab页的方法 调用简便如下&#xff1a; <link rel"stylesheet" href"kslider.css" type"text/css"/> <script type"text/javascript&q…