码迷,mamicode.com
首页 > 编程语言 > 详细

Delphi多线程编程(8)--多线程同步之CriticalSection(临界区)

时间:2015-05-11 10:26:57      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:

转载自:万一的博客

 

 先看一段程序

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!