程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 多線程編程(19) - 不使用同步工具, 手動協調線程依次執行

多線程編程(19) - 不使用同步工具, 手動協調線程依次執行

編輯:Delphi

在前面例子的基礎上, 探討新問題.

  假如我們想讓幾個線程(例子中是 3 個)依次執行, 我們可以使用臨界區、信號、互斥等手段;

  但下面第一個例子什麼同步工具都沒用, 也達到了目的; 方法是: 讓前一個線程在結束前順便啟動下一個線程.

  第二個例子使用了互斥對象配合 WaitForSingleObject 函數, 也達到相似的目的.

  效果圖(兩個例子的效果圖差不多, 但第二個例子的執行順序不好保證):

  第一個例子的代碼文件:

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;
type
 TForm1 = class(TForm)
  PaintBox1: TPaintBox;
  PaintBox2: TPaintBox;
  PaintBox3: TPaintBox;
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
const
 colors: array[0..2] of TColor = (clRed, clGreen, clBlue);
var
 hArr: array[0..2] of THandle;
 panitArr: array[0..2] of TPaintBox;
function ThreadFun(p: Pointer): Integer; stdcall;
var
 i,n,x1,y1,x2,y2: Integer;
 ThreadID: DWord;
begin
 n := Integer(p);
 panitArr[n].Color := colors[n];
 for i := 0 to 50 do with panitArr[n] do
 begin
  x1 := Random(Width); y1 := Random(Height);
  x2 := Random(Width); y2 := Random(Height);
  Canvas.Lock;
  Canvas.Ellipse(x1,y1,x2,y2);
  Canvas.Unlock;
  Sleep(2);
 end;
 {在前一個線程收尾時, 如果新建線程不超過 3 個就繼續建立}
 Inc(n);
 if n < 3 then hArr[n] := CreateThread(nil, 0, @ThreadFun, Ptr(n), 0, ThreadID);
 Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 ID: DWord;
begin
 panitArr[0] := PaintBox1;
 panitArr[1] := PaintBox2;
 panitArr[2] := PaintBox3;
 {開始只建立了一個線程, 並傳入 0 參數作為標識}
 hArr[0] := CreateThread(nil, 0, @ThreadFun, Ptr(0), 0, ID);
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
 i: Integer;
begin
 for i := 0 to Length(hArr) - 1 do CloseHandle(hArr[i]);
end;
end.

  窗體文件:

object Form1: TForm1
 Left = 0
 Top = 0
 Caption = 'Form1'
 ClIEntHeight = 156
 ClIEntWidth = 321
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'Tahoma'
 Font.Style = []
 OldCreateOrder = False
 OnDestroy = FormDestroy
 PixelsPerInch = 96
 TextHeight = 13
 object PaintBox1: TPaintBox
  Left = 8
  Top = 8
  Width = 97
  Height = 113
 end
 object PaintBox2: TPaintBox
  Left = 111
  Top = 8
  Width = 98
  Height = 113
 end
 object PaintBox3: TPaintBox
  Left = 215
  Top = 8
  Width = 98
  Height = 113
 end
 object Button1: TButton
  Left = 238
  Top = 126
  Width = 75
  Height = 25
  Caption = 'Button1'
  TabOrder = 0
  OnClick = Button1Click
 end
end

  第一個例子的代碼文件(窗體同上):

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;
type
 TForm1 = class(TForm)
  PaintBox1: TPaintBox;
  PaintBox2: TPaintBox;
  PaintBox3: TPaintBox;
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
const
 colors: array[0..2] of TColor = (clRed, clGreen, clBlue);
var
 hArr: array[0..2] of THandle;
 panitArr: array[0..2] of TPaintBox;
 hMutex: THandle; {互斥對象的句柄}
function ThreadFun(p: Pointer): Integer; stdcall;
var
 i,n,x1,y1,x2,y2: Integer;
begin
 n := Integer(p);
 panitArr[n].Color := colors[n];
 if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
 begin
  for i := 0 to 50 do with panitArr[n] do
  begin
   x1 := Random(Width); y1 := Random(Height);
   x2 := Random(Width); y2 := Random(Height);
   Canvas.Lock;
   Canvas.Ellipse(x1,y1,x2,y2);
   Canvas.Unlock;
   Sleep(10);
  end;
  ReleaseMutex(hMutex);
 end;
 Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 ID: DWord;
 i: Integer;
begin
 panitArr[0] := PaintBox1;
 panitArr[1] := PaintBox2;
 panitArr[2] := PaintBox3;
 CloseHandle(hMutex);
 hMutex := CreateMutex(nil, False, nil);
 for i := 0 to Length(hArr) - 1 do
  hArr[i] := CreateThread(nil, 0, @ThreadFun, Ptr(i), 0, ID);
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
 i: Integer;
begin
 CloseHandle(hMutex);
 for i := 0 to Length(hArr) - 1 do CloseHandle(hArr[i]);
end;
end.

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved