跟着老侯玩编程 跟着老侯玩编程
首页
  • 基础语法
  • 设计模式
  • 基础语法
  • 课程目录
  • 码农宝典
网盘 (opens new window)
留言
首页
  • 基础语法
  • 设计模式
  • 基础语法
  • 课程目录
  • 码农宝典
网盘 (opens new window)
留言
  • 基础语法

    • 单元文件
    • 变量和常量
    • 内联变量
    • 基本数据类型
    • 复合数据类型
    • 语句(选择语句)
    • 语句(循环语句)
    • 数组
    • 初识例程
    • 初识面向对象
    • 属性Property
    • 面向对象的方法
    • 指针
    • 接口
    • 匿名函数和委托实现
    • 多态
    • 字符串详解
    • 异常处理
    • 反射机制
    • 泛型容器
    • JSON
    • 文件操作
    • Dll创建并调用
    • DLL初始化和退出处理
    • Package
    • 理解消息循环
    • VCL与Windows消息
    • 钩子原理
    • 进程通讯-内存映像
    • 多线程开篇
      • API启动
      • TThread
        • OnTerminate事件
      • 注意事项
    • 线程控制
    • 线程同步
  • 设计模式

    • 单例模式
    • 单例模式二
    • 策略模式
    • 简单工厂模式
    • 建造者模式
    • 原型模式
    • 模板方法模式
    • 状态模式
    • 迭代器模式
    • 解释器模式
    • 责任链模式
    • 中介者模式
    • 备忘录模式
    • 命令模式
    • 观察者模式
    • 访问者模式
    • 适配器模式
    • 桥接模式
  • Delphi
  • 基础语法
舞动的代码
2022-05-05

多线程开篇

这是一篇很枯燥的文章,可能很多人会觉得没有什么卵用。但是只有在搞清楚理论之后才可以完美的去实现。所以这篇文章作为多线程的开篇

其实多线程是一个很大的话题,我也仅仅停留在简单的应用,至于以后的深入只能靠自己

时间切片

在大多数支持多线程的系统中,可能有许多用户在计算机系统上同时发出请求。通常,系统中的物理处理器数量少于可能并行运行的线程数量。而此时就需要依靠时间切片完成,大多数系统都支持时间切片,也称为先发制人的多任务处理。

在时间切片的系统中,线程会运行一段时间,然后被抢占; 也就是说,硬件计时器触发,导致操作系统重新评估应运行哪些线程,可能停止对当前运行的线程执行,以及运行最近未执行的其他线程。这甚至允许单处理器机器运行多个线程。在PC上,时间片往往大约是五十五毫秒。

55 毫秒的时间给人的感觉接近无感,以为是多个任务在同时运行。线程不应该改变程序的语义。他们只是改变了操作的时间。

下面几种场景我们都需要多线程的方式来完成任务

  • 进行冗长的处理:当Windows应用程序正在计算时,它无法再处理任何消息。结果,无法更新显示。

  • 进行后台处理:某些任务可能不是时间关键,但需要连续执行。

  • 执行I / O工作:磁盘或网络的I / O可能会出现不可预测的延迟。线程允许您确保I / O延迟不会延迟应用程序的不相关部分。

时间切片的概念也不小,这里不做深入讨论,仅仅产生一个认知即可

Delphi支持两种线程的启动方式,当然也有可能是 3 种

  • Win32API

  • TTHread类

  • 线程池:这种方式我没有用到,同时在掌握上面两种方式之后线程池自然也会掌握,所以我们把学习的重点放在前面两种

Delphi使得线程启动变得容易。在获取子线程执行之前,通常需要在线程中设置一些初始状态。通过创建挂起的线程(构造函数的参数),可以确保线程中的所有代码都不会执行,直到线程恢复为止。

# API启动

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btn2: TButton;
    procedure btn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
{工作线程调入函数,stdcall用于多个线程排序以及系统级别调用加此关键字}
function MyFun(p:Pointer):integer;stdcall;
var
  i:integer;
begin
  for i := 0 to 500000 do
  begin
    with Form1.Canvas do
    begin
      Lock;
      {50和10是坐标X和Y}
      TextOut(50,10,IntToStr(i));
      Unlock;
      Application.ProcessMessages;
    end;
  end;
end;


{工作线程,拖动窗口时计数不会停顿,因为和主线程分开工作了}
procedure TForm1.btn2Click(Sender: TObject);
var
    {用于接收线程返回句柄,也可以用DWORD}
  ID:THandle;
begin
  {API创建线程}
  CreateThread(nil,0,@MyFun,nil,0,ID);
end;

end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# TThread

其实在Delphi中更建议使用该类完成线程相关的操作

unit UnitThread;

interface

uses
  Vcl.Forms, Vcl.Dialogs, System.SysUtils, System.Classes;

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

implementation

uses
  UnitMain;

{ TMyThread }

procedure TMyThread.Execute;
var
  I: Integer;
begin
  FreeOnTerminate := False;
  I := 1;
  while True do begin
    if FreeOnTerminate then
      Exit;
    form1.lbl1.Caption := '线程ID:' + Self.ThreadID.ToString + ':' + I.ToString;
    TThread.Sleep(300);
    I := I + 1;
  end;

end;

end.

{启动线程的代码}

procedure TForm1.btn1Click(Sender: TObject);
begin
  Thread := TMyThread.Create(True);
  Thread.Start;
end;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

通过代码可以很明显的发现 FreeOnTerminate 这玩意儿是可以控制线程的启停

# OnTerminate事件

当线程真正完成执行时,会发生OnTerminate事件。它并没有在终止线程的方法被调用发生。此事件可能非常有用,因为它在主VCL线程的上下文中执行,就像传递给同步的方法一样。因此,如果一个人希望用一个在终止时自动释放自己的线程来执行一些VCL操作,那么这就是它的地方。

mark

# 注意事项

要记住Execute()需要经常地检查Terminated属性的值,来确认是否要提前退出。尽管这将意味着当使用线程工作的时候,你必须关心更多的事情,但它能确保在线程结束时,能够完成必要的清除

在某些紧急情况下,你可以使用Win32 API函数 TerminateThread()来终止一个线程。但是,除非没有别的办法了,否则不要使用它。

在Delphi中还可以使用TThread类的CreateAnonymousThread函数来创建线程

上次更新: 2022/05/05, 14:24:28
进程通讯-内存映像
线程控制

← 进程通讯-内存映像 线程控制→

Theme by Vdoing | Copyright © 2013-2022 冀ICP备16006233号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×