标签:
转载自:万一的博客
先看一段程序
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