标签:
转载自:万一的博客
先看一段程序
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1=class(TForm) ListBox1: TListBox; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} function MyThreadFun(p: Pointer): DWORD; stdcall; var i: Integer; begin for i:=0 to 99 do Form1.ListBox1.Items.Add(IntToStr(i)); //注意TListBox的使用方法(又学到一个组件的简单的使用) Result:= 0; end; procedure TForm1.Button1Click(Sender: TObject); var ID: DWORD; begin CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); end; procedure TForm1.FormCreate(Sender: TObject); begin ListBox1.Align:= alLeft; end; end.
窗体文件如下
object Form1: TForm1 Left = 0 Top = 0 Caption = ‘Form1‘ ClientHeight = 154 ClientWidth = 214 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = ‘Tahoma‘ Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object ListBox1: TListBox Left = 9 Top = 9 Width = 121 Height = 97 ItemHeight = 13 TabOrder = 0 end object Button1: TButton Left = 131 Top = 112 Width = 75 Height = 25 Caption = ‘Button1‘ TabOrder = 1 OnClick = Button1Click end end
在这段程序中,有三个线程几乎是同时创建,向窗体中的 ListBox1 中写入数据,最后写出的结果是这个样子的
能不能让它们别打架,一个完成了另一个再来?这就要用到多线程的同步技术
前面说过,最简单的同步手段就是“临界区”
先说这个“同步(Synchronize)”,首先这个名字起得不好,我们好像需要的是“异步”;其实“异步”也不准确.....
管它叫什么名字呢,它的目的就是保证不冲突、有次序、都发生
“临界区(CriticalSection”:当把一段代码放入一个临界区,线程执行到临界区时就独立了,让其他也要执行此代码的线程先等等;这个前面用的Lock和UnLock差不多;使用格式如下
var CS: TRTLCriticalSection; //声明一个TRTLCriticalSection 结构类型变量。它应该是全局的 InitializeCriticalSection(CS); //初始化 EnterCriticalSection(CS); //开始,轮到我了,其他线程走开 LeaveCriticalSection(CS); //结束,我执行好了,其他线程可以来了 DeleteCriticalSection(CS); //删除,注意不能过早删除 //也可以使用TryEnterCriticalSection 替代 EnterCriticalSection
用上临界区,重写上面的代码,运行的效果图如下
代码文件如下
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1=class(TForm) ListBox1: TListBox; Button: TButton; procedure FormCreate(Sender: TObject); procedure FormDestory(Sender: TObject); procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} var CS: TRTLCriticalSection; function MyThreadFun(p: Pointer): DWORD; stdcall; var i: Integer; begin EnterCriticalSection(CS); for i:=0 to 99 do Form1.ListBox1.Items.Add(IntToStr(i)); LeaveCriticalSection(CS); Result:= 0; end; procedure TForm1.Button1Click(Sender: TObject); var ID: DWORD; begin CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); end; procedure TForm1.FormCreate(Sender: TObject); begin ListBox1.Align:= alLeft; InitializeCriticalSection(CS); end; procedure TForm1.FormDestory(Sender: TObject); begin DeleteCriticalSection(CS); end; end.
Delphi在 SyncObjs单元给封装了一个 TCriticalSection 类,永达差不多,代码如下
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1=class(TForm) ListBox1: TListBox; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestory(Sender: TObject); procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses SyncObjs; var CS: TCriticalSection; function MyThreadFun(p: Pointer): DWORD; stdcall; var i: Integer; begin CS.Enter; for i:=0 to 99 do Form1.ListBox1.Item.Add(IntToStr(i)); CS.Leave; Result:= 0; end; procedure TForm1.Button1Click(Sender: TObject); var CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); end; procedure TForm1.FormCreate(Sender: TObject); begin ListBox1.Align:= alLeft; CS:= TCriticalSection.Create; end; Procedure TForm1.FormDestory(Sender: TObject); begin CS.Free; end; end.
Delphi多线程编程(8)--多线程同步之CriticalSection(临界区)
标签:
原文地址:http://www.cnblogs.com/xumenger/p/4493610.html