博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学习笔记:delphi多线程知识
阅读量:5939 次
发布时间:2019-06-19

本文共 2690 字,大约阅读时间需要 8 分钟。

最近一直在温习旧的知识,刚好学习了一下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 := 0 to 1000 do  begin     //使用WaitForSingleObject访问互斥对象,如果hMutex为被锁定>=1,那就等待,如果为未锁定那么就给hMutex的上锁,然后运行下面的代码    if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then    begin      //保护中的代码       .....             //代码结束后释放信号量,表示当前线程已经完成处理,后面的线程就可以获得控制权      ReleaseMutex(hMutex);    end;  end;  Result := 0;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代码块很像,这样写起线程同步要简化不少。

转载于:https://www.cnblogs.com/5207/p/4322336.html

你可能感兴趣的文章
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
基于事件驱动的DDD领域驱动设计框架分享(附源代码)
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
JFreeChart开发_用JFreeChart增强JSP报表的用户体验
查看>>
度量时间差
查看>>
apache prefork模式优化错误
查看>>
通过jsp请求Servlet来操作HBASE
查看>>
JS页面刷新保持数据不丢失
查看>>
清橙A1202&Bzoj2201:彩色圆环
查看>>
使用data pump工具的准备
查看>>
springMVC---级联属性
查看>>