转:学习笔记:delphi多线程学识

学习笔记: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 := 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代码块很像,这样写起线程同步要简化不少。
时间: 2024-10-13 12:22:50

转:学习笔记:delphi多线程学识的相关文章

linux网络编程学习笔记之四 -----多线程并发服务端

相对于使用进程实现并发,用线程的实现更加轻量.每个线程都是独立的逻辑流.线程是CPU上独立调度运行的最小单位,而进程是资源分配的单位.当然这是在微内核的操作系统上说的,简言之这种操作系统的内核是只提供最基本的OS服务,更多参看点击打开链接 每个线程有它自己的线程上下文,包括一个唯一的线程ID(linux上实现为unsigned long),栈,栈指针,程序计数器.通用目的寄存器和条件码,还有自己的信号掩码和优先级.同一个进程里的线程共享这个进程的整个虚拟地址空间,包括可执行的程序文本.程序的全局

【学习笔记】 多线程资源管理器(附流程图附源码)

<奇怪的大冒险>教程视频连接:http://www.taikr.com/course/222笔记结合了前7课的视频内容,感谢新总提供的免费视频PS:部分字段.属性和方法的命名与视频教程中有出入. 资源管理器核心的集合一共有三个:1.等待加载的资源队列 private Queue <ResLoadRequest> m_QueWaitLoadAsset = new Queue< ResLoadRequest >(); 2.当前正在加载的资源列表 private List &

学习笔记-java 多线程

背景说明: 多线程并发与管理,是java基础知识里的重点,本文根据<java核心技术第八版>中的多线程技术的学习,对知识点进行整理:这里只对基础知识点进行简单罗列,以达到对知识点有网状关联的效果,能起到提纲挈领的作用,在于其它知识点融合时,有更好的一览效果. 线程概念 1.明确进程与线程的区别 2.不要调用Thread或Runnable对象的run方法,直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程.应该调用Thread.start方法.这个方法将创建一个执行run方法地新线

Java学习笔记之多线程二

看到一篇讲线程的故事性文章,觉得很有意思,很佩服作者能这么生动地讲述出来,点击可跳转阅读此文章:<我是一个线程> 继续我的笔记中总结 - - 理解线程安全问题: 下面是书上看到的卖票例子:模拟3个窗口同时在售10张票. 上篇博文笔记总结了多线程创建的两种方式,那我们就分别以这两种实现多线程的方式来解决这个场景. 使用继承于Thread类的方式 上Demo: class SaleTicket extends Thread { int num = 10; // 票数 public SaleTick

Java学习笔记之多线程

/* 进程: 正在进行中的程序(直译). 线程: 就是进程中一个负责程序执行的控制单元(执行路径) 一个进程中可以有多个执行路径, 称之为多线程. 一个进程中至少要有一个线程. 开启多个线程是为了同时运行多部分代码. 每一个线程都有自己运行的内容. 这个内容可以称为线程要执行的任务. 多线程的好处: 解决了多部分同时运行的问题. 多线程的弊端: 线程太多回到效率的降低. 其实应用程序的执行都是cpu在做着快速的切换完成的. 这个切换是随机的. jvm启动时就启动了多个线程,至少有两个线程可以分析

python 学习笔记day10-python多线程,forking,xinetd服务

xinetd服务器 配置xinetd服务 什么是xinetd xinetd可以统一管理很多服务进程,它能够: - 绑定.侦听和接受来对自服务器每个端口的请求 - 有客户访问时,调用相应的服务器程序相应 - 节约了系统内存资源 - 同时响应多个客户端的连接请求 Windows系统没有该功能 多数UNIX系统使用的是inetd实现相同的功能 配置文件解析 选项名称 说明 flags 如果只指定NAMEINARGS,那么它就使参数和inetd一样的传递 type 如果服务不在/etc/services

2016年4月20日_JAVA学习笔记_多线程

1.感觉书里的东西没什么意思了,继续来看毕老师的视频好了.今天家里就剩我一个人了,可以出去吃饭了. 2.程序中每一个任务称为一个线程,同时可以控制多个任务的程序称为多线程程序.与多进程(进程也就是WIN任务管理器中的)的区别在于,进程之间是独立的,不共享数据,而线程是共享数据的,同时线程更加简单,轻量,最后一个进程中可以有多个线程. 3.在多个线程运行的过程中,线程间的切换是由CPU控制的,这个切换是随机的.JVM的运行时就包含了多个线程.

Java学习笔记-8.多线程编程

一.引入线程 1.多线程和多进程的区别 (1)两者粒度不同,进程是由操作系统来管理,而线程则是在一个进程内 (2)每个进程是操作系统分配资源和处理器调度的基本单位,拥有独立的代码.内部数据和状态 而一个进程内的多线程只是处理器调度的基本单位,共享该进程的资源,线程间有可能相互影响 (3)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担小 2.Thread类:Java的线程是通过java.lang.Thread类来实现,一个Thread对象代表一个线程

黑马程序员——JAVA学习笔记六(多线程)

1,    什么是多线程?一个程序可以执行多个任务,每一个任务称为一个线程,运行多个线程的程序称为多线程程序. 进程:正在进行中的程序(直译). 线程:进程中一个负责程序执行的控制单元(执行路径).   多线程的好处:解决了多部分代码同时运行的问题.多线程的弊端:线程太多,会导致效率的降低. 其实,多个应用程序同时执行都是CPU在做着快速的切换完成的.这个切换是随机的.CPU的切换是需要花费时间的,从而导致了效率的降低 2 ,    创建线程方式:  创建线程方式一:继承Thread类 1.定义