首页 > 代码库 > delphi 多线程2

delphi 多线程2

多线程常用的内核对象:CreateEvent事件,CreateMutex互斥,CreateSemaphore信号,CreateWaitableTimer计时器

{建立事件}function CreateEvent(  lpEventAttributes: PSecurityAttributes; {!}  bManualReset: BOOL;  bInitialState: BOOL;  lpName: PWideChar): THandle; stdcall;{建立互斥}function CreateMutex(  lpMutexAttributes: PSecurityAttributes; {!}  bInitialOwner: BOOL;  lpName: PWideChar): THandle; stdcall;{建立信号}function CreateSemaphore(  lpSemaphoreAttributes: PSecurityAttributes; {!}  lInitialCount: Longint;  lMaximumCount: Longint;  lpName: PWideChar): THandle; stdcall;{建立等待计时器}function CreateWaitableTimer(  lpTimerAttributes: PSecurityAttributes; {!}  bManualReset: BOOL;  lpTimerName: PWideChar): THandle; stdcall;

上面的四个系统内核对象(事件、互斥、信号、计时器)都是线程同步的手段, 从这也能看出处理线程同步的复杂性; 不过这还不是全部, Windows Vista 开始又增加了 Condition variables(条件变量)、Slim Reader-Writer Locks(读写锁)等同步手段.
不过最简单、最轻便(速度最快)的同步手段还是 CriticalSection(临界区), 但它不属于系统内核对象, 当然也就没有句柄、没有 TSecurityAttributes 这个安全属性, 这也导致它不能跨进程使用; 不过写多线程时一般不用跨进程啊, 所以 CriticalSection 应该是最常用的同步手段.

------------------------------------------------------------------------------------------------------------------------------------------------------------

先介绍临界区(不是内核对象,不能跨进程):作用,独占共享资源的的访问权(同一时间内只有一个线程可以修改共享资源

更多理解祥见:http://www.cnblogs.com/760044827qq/p/4158640.html

"临界区"(CriticalSection): 当把一段代码放入一个临界区, 线程执行到临界区时就独占了, 让其他也要执行此代码的线程先等等;

var CS: TRTLCriticalSection;   {声明一个 TRTLCriticalSection 结构类型变量; 它应该是全局的}InitializeCriticalSection(CS); {初始化}EnterCriticalSection(CS);      {开始: 轮到我了其他线程走开}LeaveCriticalSection(CS);      {结束: 其他线程可以来了}DeleteCriticalSection(CS);     {删除: 注意不能过早删除}

Delphi 在 SyncObjs 单元给封装了一个 TCriticalSection 类,用法和API类似。

------------------------------------------------------------------------------------------------------------------------------------------------------------

等待函数

function WaitForSingleObject(
  hHandle: THandle;      {要等待的对象句柄}
  dwMilliseconds: DWORD  {等待的时间, 单位是毫秒;如果是INFINITE,就是一直等。}
): DWORD; stdcall;       {返回值如下:}

WAIT_OBJECT_0  {等着了, 本例中是: 等的那个进程终于结束了}
WAIT_TIMEOUT   {等过了点(你指定的时间), 也没等着}
WAIT_ABANDONED {好不容易等着了, 但人家还是不让咱执行; 这一般是互斥对象}

------------------------------------------------------------------------------------------------------------------------------------------------------------

原理分析: 互斥对象是系统内核对象, 各线程都可以拥有它, 谁拥有谁就能执行; 执行完毕, 用 ReleaseMutex 函数释放拥有权, 以让其他等待的线程使用. 其他线程可用 WaitForSingleObject 函数排队等候(等候也可以理解为排队申请).
使用过程:

var hMutex: THandle; {应该先声明一个全局的互斥句柄}CreateMutex          {建立一个互斥对象}WaitForSingleObject  {用等待函数排队等候}ReleaseMutex         {释放拥有权}CloseHandle          {最后释放互斥对象}

ReleaseMutex、CloseHandle 的参数都是 CreateMutex 返回的句柄, 关键是 CreateMutex 函数:

function CreateMutex(  lpMutexAttributes: PSecurityAttributes;  bInitialOwner: BOOL; {是否让创建者(此例中是主线程)拥有该互斥对象}  lpName: PWideChar    {可以给此互斥对象取个名字, 如果不要名字可赋值为 nil}): THandle;{1、第一个参数前面说过.2、第二个参数在这里一定要是 False, 如果让主线程拥有互斥, 从理论上讲, 得等程序退出后其他线程才有机会;   取值 False 时, 第一个执行的线程将会最先拥有互斥对象, 一旦拥有其他线程就得先等等.3、第三个参数, 如果给个名字, 函数将从系统中寻找是否有重名的互斥对象, 如果有则返回同名对象的存在的句柄;   如果赋值为 nil 将直接创建一个新的互斥对象; 下个例子将会有名字. }
Delphi 在 SyncObjs 单元给封装了一个 TCriticalSection 类,用法和API类似。

------------------------------------------------------------------------------------------------------------------------------------------------------------

delphi 多线程2