学习笔记:delphi多线程知识
最近一直在温习旧的知识,刚好学习了一下Java的线程安全方面的知识,今天想起之前一直做的Delphi开发,所以还是有必要温习一下,看看这些不同的编程语言有什么不同之处。
Delphi的线程同步方法:
1、临界区
申明一个临界资源
FLock : TRTLCriticalSection;
先初化一个临界资源对象
InitializeCriticalSection(FLock)
销毁临界资源对象
DeleteCriticalSection(FLock)
procedure TSaveThread.PushTask(pTask: pFileInfo);
begin
//进入临界资源,有线程占用后,后面的线程会阻塞
EnterCriticalSection(FLock);
try
//这里是受保护的代码
if not Assigned(FTasks) then
FTasks:= TList.Create; FTasks.Add(pTask);
finally
//离开临界资源,其他的阻塞的线程可以进入
LeaveCriticalSection(FLock);
end;
end;
这种方式还是挺简单的,和Java中的synchronized代码块方式类似
2、Event事件
Event有两种状态:有信号和无信号,通过这个特性可以用于线程同步。Event相关的API也多,控制起来也比较灵活,看看他的几个方法:
CreateEvent:创建事件
SetEvent:设置为有信号状态
ResetEvent: 设置为无信号状态
PulseEvent :设置为有信号状态,接着又设置为无信号状态(有点类似于单步调试的感觉)
在线程中还是要用WaitForSingleObject来阻塞
procedure TSearchTopNThread.Execute;
begin
while not Self.Terminated do
begin
WaitForSingleObject(FEvent, INFINITE);//FEvent为无信号时阻塞,直到变为有信号时代码继续执行
.......
end;
end;
//设置事件状态为无信号,阻塞线程
procedure TForm1.Button1Click(Sender: TObject);
begin
ResetEvent(hEvent);
end; //设置事件状态为有信号,线程解除阻塞
procedure TForm1.Button2Click(Sender: TObject);
begin
SetEvent(hEvent);
end; //设置一次脉冲信号状态,先设置有信号,再设置无信号
procedure TForm1.Button3Click(Sender: TObject);
begin
PulseEvent(hEvent);
end;
3、互斥对象
var hMutex: THandle; //互斥对象的句柄 function ThreadFun(p: Pointer): DWORD; stdcall;
var
i: Integer;
beginfor i := to do
begin
//使用WaitForSingleObject访问互斥对象,如果hMutex为被锁定>=1,那就等待,如果为未锁定那么就给hMutex的上锁,然后运行下面的代码
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_ then
begin //保护中的代码
..... //代码结束后释放信号量,表示当前线程已经完成处理,后面的线程就可以获得控制权
ReleaseMutex(hMutex);
end;
end;
Result := ;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
hMutex := CreateMutex(nil, False, nil);//第二个参数为False表示创建的互斥对象不被任何线程拥有,也就说初始状态为未锁定,线程可以占有
end; procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(hMutex);
end; end.
总的过程和临界区有些类似,只不过互斥对象是系统核心对象,可以跨进程,而临界区只是当前进程。有这个特性可以用于对文件等资源的并发保护。
4、信号量
信号量与互斥对象的方法类似,信号量的特点是可以设置计数,就是同时可以允许多个线程同时访问同一段代码。互斥对象就是信号量为1的情况,后面的线程只能等前一个执行完,而信号量就可以允许指定多个执行。
后来在看TThread的代码时发现新的Delphi版本中有了一个好东西:TMnitor
try
TMonitor.Enter(ThreadLock);
try
SyncProcPtr.Queued := QueueEvent;
if SyncList = nil then
SyncList := TList.Create;
SyncProcPtr.SyncRec := ASyncRec;
SyncList.Add(SyncProcPtr);
SignalSyncEvent;
if Assigned(WakeMainThread) then
WakeMainThread(SyncProcPtr.SyncRec.FThread);
if not QueueEvent then
TMonitor.Wait(SyncProcPtr.Signal, ThreadLock, INFINITE)
finally
TMonitor.Exit(ThreadLock);
end;
这个代码和java中的Synchronized代码块很像,这样写起线程同步要简化不少。
学习笔记:delphi多线程知识的更多相关文章
- 孙鑫VC学习笔记:多线程编程
孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010 HQU Email:zgzhaobo@gmail.com QQ:452728574 Latest Modified ...
- MyBatis:学习笔记(1)——基础知识
MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...
- C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)
一:值类型和引用类型的含义参考前一篇文章 C#学习笔记(基础知识回顾)之值类型和引用类型 1.1,C#数据类型分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型.如果int只不过是栈上的一个4字 ...
- C#学习笔记(基础知识回顾)之值传递和引用传递
一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...
- C#学习笔记(基础知识回顾)之值类型和引用类型
一:C#把数据类型分为值类型和引用类型 1.1:从概念上来看,其区别是值类型直接存储值,而引用类型存储对值的引用. 1.2:这两种类型在内存的不同地方,值类型存储在堆栈中,而引用类型存储在托管对上.存 ...
- JAVA学习笔记—review基本知识[反射与异常]
JAVA学习笔记—review基本知识[反射与异常] 1.异常: 1.1异常的分类: Java会将所有的异常封装成对象,其根本父类为Throwable. Throwable有两个子类:Error 和E ...
- Quartz学习笔记:基础知识
Quartz学习笔记:基础知识 引入Quartz 关于任务调度 关于任务调度,Java.util.Timer是最简单的一种实现任务调度的方法,简单的使用如下: import java.util.Tim ...
- 大数据学习笔记——Linux基本知识及指令(理论部分)
Linux学习笔记整理 上一篇博客中,我们详细地整理了如何从0部署一套Linux操作系统,那么这一篇就承接上篇文章,我们仔细地把Linux的一些基础知识以及常用指令(包括一小部分高级命令)做一个梳理, ...
- .net学习笔记---xml基础知识
一.XML简介 XML是一种标记语言,用于描述数据,它提供一种标准化的方式来来表示文本数据.XML文档以.xml为后缀.需要彻底注意的是XML是区分大小写的. 先从一个简单的XML例子来了解下xml基 ...
- react学习笔记1--基础知识
什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...
随机推荐
- git 创建分支 并 提交到远程分支
git branch(分支命令的使用http://hbiao68.iteye.com/blog/2055493 0.可以通过git branch -r 命令查看远端库的分支情况 1,从已有的分支创建新 ...
- Android 敏感 API 的说明
从中国的国情来看,Google 的诸多产品,包括 gmail,Android 官方市场 Google Play 正处于并将长期处于访问不了的状态.国内几亿网民也要生活,于是墙内出现了“百家争鸣”的场面 ...
- c#3.0新特性
1.自动属性 public int ID { get; set; } // 上面的ID属性(自动属性)等同于下面的ID属性 // private int _id; // public int ID / ...
- 解决MVC4 时间验证Bug
MVC验证时间控件(my97,时间格式:yyyy-MM-dd HH:mm:ss) 在谷歌浏览器上一切正常.但在火狐和IE 上一直验证不通过 (错误信息:日期格式不对) 猜想是 时间格式的问题..日期 ...
- StartCom 申请 SSL 证书及 Nginx HTTPS 支持配置全攻略
来源:https://www.williamyao.com/index.php/archives/1397/ 前言 最近收到 StartCom 的邮件,数字证书即将过期,想到去年在 StartSSL ...
- unicode 和 utf8
关于 unicode utf8 文章来自于 http://blog.csdn.net/tge7618291/article/details/7599902 ascii 主要来表示英文.但是要全世界那么 ...
- PDA手持终端扫描条码开单打印一体 结合后台电脑系统 数据同步交互解决方案
PDA通过扫描商品条码移动开单,实现便携式办公,伴随式销售,PDA能通过WIFI无线局域网.GPRS互联网直接与主机连接,让公司业务人员能随时随地了解公司产品信息,直接扫描商品条码,进行开单.入库.库 ...
- Swift学习之熟悉控件
最近是比较清闲一些的,对于一个开发者来说,这也是一个很好的充电机会.以前做项目都是使用Objective-C去开发,但我们都知道,Swift语言从2014年的出现到现在,一步一步变的完善,渐渐变的受欢 ...
- 6种方法实现asp.net返回上一页
其实要实现返回上一页的功能,主要还是要用到JavaScript. 一: 在ASP.net的aspx里面的源代码中 <input type="button onclick="J ...
- LeetCode 1. Two Sum
Problem: Given an array of integers, return indices of the two numbers such that they add up to a sp ...