之前学习了用API实现,让我们再学习下用DELPHI的TThread类。

先新建一个普通的工程,再新建一个线程类File>>New>>Othre>>Delphi File>Thread Object,取个名字,DELPHI会自动生成一个单元,我们只需往里简单添加功能代码,和在要使用的单元里实例引用即可。

为了节省篇幅,现把TMyThread类集成主窗体单元里,在窗体单元里声明类也是可以的。

例:用工作线程在窗体输出0~500000的数字。

 1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls;
8
9 type
10 TMyThread = class(TThread)
11 private
12 { Private declarations }
13 protected
14 procedure Execute; override; {执行}
15 procedure Run; {声明多一个过程,把功能代码写在这里再给Execute调用}
16 end;
17 TForm1 = class(TForm)
18 btn1: TButton;
19 procedure btn1Click(Sender: TObject);
20 private
21 { Private declarations }
22 public
23 { Public declarations }
24 end;
25
26
27
28 var
29 Form1: TForm1;
30
31
32 implementation
33
34 {$R *.dfm}
35
36 var
37 MyThread:TMyThread; {声明一个线程类对象]
38
39 procedure TMyThread.Execute;
40 begin
41 { Place thread code here }
42 FreeOnTerminate:=True; {加上这句线程用完了会自动注释}
43 Run;
44 end;
45
46 procedure TMyThread.Run;
47 var
48 i:integer;
49 begin
50 for i := 0 to 500000 do
51 begin
52 Form1.Canvas.Lock;
53 Form1.Canvas.TextOut(10,10,IntToStr(i));
54 Form1.Canvas.Unlock;
55 end;
56 end;
57
58 procedure TForm1.btn1Click(Sender: TObject);
59 begin
60 MyThread:=TMyThread.Create(False); {实例化这个类,为False时立即运行,为True时可加MyThread.Resume用来启动}
61 end;

CriticalSection(临界区)

uses SyncObjs;用TCriticalSection类的方法处理。

例:用三个线程,按顺序给ListBox添加0~99.

 1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls;
8
9 type
10 TMyThread = class(TThread)
11 private
12 { Private declarations }
13 protected
14 procedure Execute; override; {执行}
15 procedure Run; {运行}
16 end;
17 TForm1 = class(TForm)
18 btn1: TButton;
19 lst1: TListBox;
20 procedure btn1Click(Sender: TObject);
21 procedure FormDestroy(Sender: TObject);
22 private
23 { Private declarations }
24 public
25 { Public declarations }
26 end;
27
28
29
30 var
31 Form1: TForm1;
32
33
34 implementation
35
36 {$R *.dfm}
37
38 uses SyncObjs;
39
40 var
41 MyThread:TMyThread; {声明线程}
42 CS:TCriticalSection; {声明临界}
43
44
45 procedure TMyThread.Execute;
46 begin
47 { Place thread code here }
48 FreeOnTerminate:=True; {加上这句线程用完了会自动注释}
49 Run; {运行}
50 end;
51
52 procedure TMyThread.Run;
53 var
54 i:integer;
55 begin
56 CS.Enter; {我要用了,其它人等下}
57 for i := 0 to 100 - 1 do
58 begin
59 Form1.lst1.Items.Add(IntToStr(i));
60 end;
61 CS.Leave; {我用完了,下一个}
62 end;
63
64 procedure TForm1.btn1Click(Sender: TObject);
65 begin
66 CS:=TCriticalSection.Create; {实例化临界}
67 MyThread:=TMyThread.Create(False); {实例化这个类,为False时立即运行,为True时可加MyThread.Resume用来启动}
68 MyThread:=TMyThread.Create(False);
69 MyThread:=TMyThread.Create(False);
70 end;
71
72
73 procedure TForm1.FormDestroy(Sender: TObject);
74 begin
75 CS.Free;{释放临界体}
76 end;
77
78 end.

Mutex (互斥对象)

uses SyncObjs;用TMutex类的方法处理(把释放语句放在循环内外可以决定执行顺序)

例:互斥输出三个0~2000的数字到窗体在不同位置。

 1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls;
8
9 type
10 TMyThread = class(TThread)
11 private
12 { Private declarations }
13 protected
14 procedure Execute; override; {执行}
15 procedure Run; {运行}
16 end;
17 TForm1 = class(TForm)
18 btn1: TButton;
19 procedure FormDestroy(Sender: TObject);
20 procedure btn1Click(Sender: TObject);
21 private
22 { Private declarations }
23 public
24 { Public declarations }
25 end;
26
27
28
29 var
30 Form1: TForm1;
31
32
33 implementation
34
35 {$R *.dfm}
36
37 uses SyncObjs;
38
39 var
40 MyThread:TMyThread; {声明线程}
41 Mutex:TMutex; {声明互斥体}
42 f:integer;
43
44
45 procedure TMyThread.Execute;
46 begin
47 { Place thread code here }
48 FreeOnTerminate:=True; {加上这句线程用完了会自动注释}
49 Run; {运行}
50 end;
51
52 procedure TMyThread.Run;
53 var
54 i,y:integer;
55 begin
56 Inc(f);
57 y:=20*f;
58 for i := 0 to 2000 do
59 begin
60 if Mutex.WaitFor(INFINITE)=wrSignaled then {判断函数,能用时就用}
61 begin
62 Form1.Canvas.Lock;
63 Form1.Canvas.TextOut(10,y,IntToStr(i));
64 Form1.Canvas.Unlock;
65 Sleep(1);
66 Mutex.Release; {释放,谁来接下去用}
67 end;
68 end;
69 end;
70
71 procedure TForm1.btn1Click(Sender: TObject);
72 begin
73 f:=0;
74 Repaint;
75 Mutex:=TMutex.Create(False); {参数为是否让创建者拥有该互斥体,一般为False}
76 MyThread:=TMyThread.Create(False);
77 MyThread:=TMyThread.Create(False);
78 MyThread:=TMyThread.Create(False);
79 end;
80
81 procedure TForm1.FormDestroy(Sender: TObject);
82 begin
83 Mutex.Free;{释放互斥体}
84 end;
85
86 end.

Semaphore(信号或叫信号量)

{DELPHI2007不支持信号量,DELPHI2009才开始支持}

 1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls;
8
9 type
10 TForm1 = class(TForm)
11 Button1: TButton;
12 Edit1: TEdit;
13 procedure Button1Click(Sender: TObject);
14 procedure FormCreate(Sender: TObject);
15 procedure FormDestroy(Sender: TObject);
16 procedure Edit1KeyPress(Sender: TObject; var Key: Char);
17 end;
18
19 var
20 Form1: TForm1;
21
22 implementation
23
24 {$R *.dfm}
25
26 uses SyncObjs;
27 var
28 f: Integer;
29 MySemaphore: TSemaphore;
30
31 function MyThreadFun(p: Pointer): DWORD; stdcall;
32 var
33 i,y: Integer;
34 begin
35 Inc(f);
36 y := 20 * f;
37 if MySemaphore.WaitFor(INFINITE) = wrSignaled then
38 begin
39 for i := 0 to 1000 do
40 begin
41 Form1.Canvas.Lock;
42 Form1.Canvas.TextOut(20, y, IntToStr(i));
43 Form1.Canvas.Unlock;
44 Sleep(1);
45 end;
46 end;
47 MySemaphore.Release;
48 Result := 0;
49 end;
50
51 procedure TForm1.Button1Click(Sender: TObject);
52 var
53 ThreadID: DWORD;
54 begin
55 if Assigned(MySemaphore) then MySemaphore.Free;
56 MySemaphore := TSemaphore.Create(nil, StrToInt(Edit1.Text), 5, ''); {创建,参数一为安全默认为nil,参数2可以填写运行多少线程,参数3是运行总数,参数4可命名用于多进程}
57
58 Self.Repaint;
59 f := 0;
60 CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
61 CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
62 CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
63 CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
64 CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
65 end;
66
67 {让 Edit 只接受 1 2 3 4 5 五个数}
68 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
69 begin
70 if not CharInSet(Key, ['1'..'5']) then Key := #0;
71 end;
72
73 procedure TForm1.FormCreate(Sender: TObject);
74 begin
75 Edit1.Text := '1';
76 end;
77
78 procedure TForm1.FormDestroy(Sender: TObject);
79 begin
80 if Assigned(MySemaphore) then MySemaphore.Free;
81 end;
82
83 end.

 Event (事件对象)

注:相比API的处理方式,此类没有启动步进一次后暂停的方法。

  1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls;
8
9 type
10 TMyThread = class(TThread)
11 private
12 { Private declarations }
13 protected
14 procedure Execute; override;
15 procedure Run;
16 end;
17
18 TForm1 = class(TForm)
19 btn1: TButton;
20 btn2: TButton;
21 btn3: TButton;
22 btn4: TButton;
23 procedure btn1Click(Sender: TObject);
24 procedure FormDestroy(Sender: TObject);
25 procedure btn2Click(Sender: TObject);
26 procedure btn3Click(Sender: TObject);
27 procedure btn4Click(Sender: TObject);
28 procedure FormCreate(Sender: TObject);
29 private
30 { Private declarations }
31 public
32 { Public declarations }
33 end;
34
35 var
36 Form1: TForm1;
37
38 implementation
39
40 {$R *.dfm}
41
42 uses SyncObjs;
43
44 var
45 f:integer;
46 MyEvent:TEvent;
47 MyThread:TMyThread;
48
49 { TMyThread }
50
51
52 procedure TMyThread.Execute;
53 begin
54 inherited;
55 FreeOnTerminate:=True; {线程使用完自己注销}
56 Run;
57 end;
58
59 procedure TMyThread.Run;
60 var
61 i,y:integer;
62 begin
63 Inc(f);
64 y:=20*f;
65
66 for i := 0 to 20000 do
67 begin
68 if MyEvent.WaitFor(INFINITE)=wrSignaled then {判断事件在用没,配合事件的启动和暂停,对事件相关线程起统一控制}
69 begin
70 Form1.Canvas.lock;
71 Form1.Canvas.TextOut(10,y,IntToStr(i));
72 Form1.Canvas.Unlock;
73 Sleep(1);
74 end;
75
76 end;
77
78 end;
79
80 procedure TForm1.btn1Click(Sender: TObject);
81 begin
82 Repaint;
83 f:=0;
84 if Assigned(MyEvent) then MyEvent.Free; {如果有,就先销毁}
85
86 {参数1安全设置,一般为空;参数2为True时可手动控制暂停,为Flase时对象控制一次后立即暂停
87 参数3为True时对象建立后即可运行,为false时对象建立后控制为暂停状态,参数4为对象名称,用于跨进程,不用时默认''}
88 MyEvent:=TEvent.Create(nil,True,True,''); {创建事件}
89
90 end;
91
92 procedure TForm1.btn2Click(Sender: TObject);
93 var
94 ID:DWORD;
95 begin
96 MyThread:=TMyThread.Create(False); {创建线程}
97 end;
98
99 procedure TForm1.btn3Click(Sender: TObject);
100 begin
101 MyEvent.SetEvent; {启动} {事件类没有PulseEvent启动一次后轻描谈写}
102 end;
103
104 procedure TForm1.btn4Click(Sender: TObject);
105 begin
106 MyEvent.ResetEvent; {暂停}
107 end;
108
109 procedure TForm1.FormCreate(Sender: TObject);
110 begin
111 btn1.Caption:='创建事件';
112 btn2.Caption:='创建线程';
113 btn3.Caption:='启动';
114 btn4.Caption:='暂停';
115 end;
116
117 procedure TForm1.FormDestroy(Sender: TObject);
118 begin
119 MyEvent.Free; {释放}
120 end;
121
122 end.

总结:

多线程用TThread类以及Uses syncobjs后使用的 TCriticalSection (临界区),TMutex(互斥体),TSemaphore (信号对象,D2009才开始有),TEvent (事件对象)很多都是引用了API的方法进行了一定的简化,不过也有部分功能的缺失,如Event (事件对象)缺少了启动步进一次后暂停的功能,不过基本在同步上已经够用了,另外在TThread类声明的Execute过程里,加上FreeOnTerminate := True;这句会让线程执行完后自动释放,还可以把功能代码的方法套在Synchronize()里,用于同步一些非线程安全的控件对象,避免多个线程同时对一个对象操作引发的问题。

DELPHI 多线程(TThread类的实现)的更多相关文章

  1. 转:学习笔记: Delphi之线程类TThread

    学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...

  2. 学习笔记: Delphi之线程类TThread

    新的公司接手的第一份工作就是一个多线程计算的小系统.也幸亏最近对线程有了一些学习,这次一接手就起到了作用.但是在实际的开发过程中还是发现了许多的问题,比如挂起与终止的概念都没有弄明白,导致浪费许多的时 ...

  3. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  4. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  5. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  6. [转]Delphi多线程编程入门(二)——通过调用API实现多线程

    以下是一篇很值得看的关于Delphi多线程编程的文章,内容很全面,建议收藏. 一.入门 ㈠. function CreateThread(    lpThreadAttributes: Pointer ...

  7. [转]Delphi多线程编程入门(一)

    最近Ken在比较系统地学习Delphi多线程编程方面的知识,在网络上查阅了很多资料.现在Ken将对这些资料进行整理和修改,以便收藏和分享.内容基本上是复制粘贴,拼拼凑凑,再加上一些修改而来.各个素材的 ...

  8. 【转】Delphi多线程编程

    文章来源: http://liukun966123.my.gsdn.net/2004/10/22/4797/ Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书 ...

  9. TThread类详解

    TThread是一个抽象类,可以创建几个独立的线程.类关系 TObject在一个多线程的应用程序中创建一个TThread的后子类代表一个线程.每一新子类的TThread对象的实例是一个新的线程.从TT ...

随机推荐

  1. 人生苦短_我用Python_str(字符串)_001

    # 字符串 str str_1 = 'hello,selenium,888,999' # 切片/截断 # 更换大小写 upper/lower 英文字符 print(str_1.upper()) pri ...

  2. 【leetcode】915. Partition Array into Disjoint Intervals

    题目如下: 解题思路:题目要求的是在数组中找到一个下标最小的index,使得index左边(包括自己)子序列的最大值小于或者等于右边序列的最小值.那么我们可以先把数组从最左边开始到数组最右边所有子序列 ...

  3. 初识sed和gwak

    一.sed编辑器 sed命令的格式如下: sed options script file 选项 -e script        在处理输入时,将script中指定的命令添加到已有的命令中 -f fi ...

  4. I2C用户态驱动设计

    一.用户态驱动模型 1.1 I2C通用驱动代码 i2c_dev_init: static int __init i2c_dev_init(void) { int res; printk(KERN_IN ...

  5. hdu 6085 Rikka with Candies (set计数)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  6. oracle中解决中文乱码问题

    中文乱码问题解决 1.查看服务器端编码 select userenv('language') from dual; 查到结果是: USERENV('LANGUAGE') --------------- ...

  7. Windows-WAMP搭建与配置

    使用 WampServer 整合软件包进行 WAMP 环境搭建 WampServer 是一款由法国人开发的 Apache Web 服务器.PHP 解释器以及 MySQL 数据库的整合软件包.免去了开发 ...

  8. new运算符工作原理(new运算符的伪码实现)

    // 只要函数创建,就有一个prototype属性// 构造函数和普通函数的区别就是调用的时候又没有用 new function Fn() { // this 就是实例化后的对象 三段式 var th ...

  9. upc组队赛2 Hakase and Nano【思维博弈】

    Hakase and Nano 题目描述 Hakase and Nano are playing an ancient pebble game (pebble is a kind of rock). ...

  10. activiti7流程变量的测试(设置全局变量)

    package com.zcc.activiti03; import org.activiti.engine.*;import org.activiti.engine.repository.Deplo ...