首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Self在Delphi中挂起一个不需要的线程并安全恢复

在Delphi中,Self关键字表示当前对象的实例。要挂起一个不需要的线程并安全恢复,可以使用以下方法:

  1. 线程挂起:
代码语言:delphi
复制
TThread.Suspend;
  1. 线程恢复:
代码语言:delphi
复制
TThread.Resume;
  1. 线程安全恢复:
代码语言:delphi
复制
TThread.Synchronize(nil, procedure
begin
  TThread.Resume;
end);

这样可以确保在恢复线程之前,线程不会执行任何代码。

以下是一个简单的示例,演示如何在Delphi中挂起和恢复线程:

代码语言:delphi
复制
unit MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

  TForm1 = class(TForm)
    btnStart: TButton;
    btnSuspend: TButton;
    btnResume: TButton;
    procedure btnStartClick(Sender: TObject);
    procedure btnSuspendClick(Sender: TObject);
    procedure btnResumeClick(Sender: TObject);
  private
    FMyThread: TMyThread;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    Sleep(1000);
    TThread.Queue(nil, procedure
    begin
      Form1.Caption := 'Thread is running';
    end);
  end;
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  FMyThread := TMyThread.Create(True);
  FMyThread.Start;
end;

procedure TForm1.btnSuspendClick(Sender: TObject);
begin
  TThread.Suspend;
  TThread.Synchronize(nil, procedure
  begin
    Form1.Caption := 'Thread is suspended';
  end);
end;

procedure TForm1.btnResumeClick(Sender: TObject);
begin
  TThread.Resume;
  TThread.Synchronize(nil, procedure
  begin
    Form1.Caption := 'Thread is running';
  end);
end;

end.

在这个示例中,我们创建了一个名为TMyThread的线程类,并在主窗体中创建了一个TMyThread的实例。我们使用btnStart按钮启动线程,使用btnSuspend按钮挂起线程,使用btnResume按钮恢复线程。

请注意,挂起和恢复线程可能会导致死锁和竞争条件,因此请谨慎使用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

学习笔记: Delphi线程类TThread

但是实际开发过程还是发现了许多问题,比如挂起与终止概念都没有弄明白,导致浪费许多时间。...TThread-简单开始 DelphiVCL中封装了一个TThread类用于多线程开发,这样比较符合面向对象思想,同时又可以提高开发效率,一般情况下开发都是通过派生这个类来实现多线程。...线程挂起 线程还支持挂起功能,即让CPU将线程中断,保留现场,不再分配时间片,这样线程就像死了一般,直到再次唤醒线程恢复现场继续执行。...线程终止 DelphiTThread类实现,可以通过一个Terminate方法来让线程终止。但事实上Terminated只是一个标识而已,在线程启动时这个标识为False。...ThreadProc方法,它是线程创建时传给系统API回调函数;Delphi通过这个方法完成了一个核心功能,可以看到代码调用了Execute方法。

2.2K80

C++ CreateThread使用

实际上不管线程属于哪个进程, 它们系统怀抱是平等; 优先级(后面详谈)相同情况下, 系统会在相同时间间隔内来运行一下每个线程, 不过这个间隔很小很小, 以至于让我们误以为程序是不间断地运行...这时你应该有一个疑问: 系统去执行其他线程时候, 是怎么记住前一个线程数据状态?...ResumeThread 恢复线程运行; SuspendThread 挂起线程. 这两个函数参数都是线程句柄, 返回值是执行前挂起计数. 什么是挂起计数?...当这个数 = 0 时, 线程会运行; > 0 时会挂起. 如果被 SuspendThread 多次, 同样需要 ResumeThread 多次才能恢复线程运行....为解决这个问题 Delphi 为我们提供了一个类似 var ThreadVar 关键字, 线程使用 ThreadVar 声明全局变量时会在各自一个副本, 这样就解决了冲突.

1.2K30
  • 如何解决DLL入口函数创建或结束线程时卡死

    1) DLL_PROCESS_ATTACH 事件 创建线程 出现卡死问题 通常情况下在这事件仅仅是创建唤醒线程,是不会卡死,但如果同时有等待线程正式执行代码,则会卡死,因为该事件...LdrpLoaderLock是系统PE Loader一个重要锁,保证系统资源安全,而DLL 入口函数是PE Loader 结束前执行,LdrInitializeThunk等函数处理PE 映像...另外有一个特殊现象,就是DLL_PROCESS_DETACH事件线程处于挂起状态,这是因为系统分配线程执行时间片过程由于PE Loader有资源处于锁定而导致线程无法进行下一个时间片,最终表现为线程函数处于假死状态...,此状态基本上等同于线程挂起(suspend)状态。...解决办法同样是避免 DLL_PROCESS_DETACH事件结束线程,那么我们可以该事件,创建唤醒另外一个线程该新线程里,结束需要结束线程,并在完成后结束自身即可。

    3.8K10

    Continuation - 连接异步任务和同步代码

    continuations 上,异步任务可以挂起自身,同步代码能够捕获调用 continuations 来恢复任务,响应事件。...获取任务 continuation 会挂起该任务,产生一个值,同步代码可以使用 handle 来恢复任务。...这当然符合 Swift 常见理念,即首选安全接口,性能是首要考虑因素情况下,有选择得使用不安全接口。...unsafeResumeImmediately,并且一段可能无限时间内,从调用者接管当前线程控制权是安全。...删除了一个必须调用resume时不必要不变量;with*Continuation操作开始执行后任何一个时间点,仅能有效调用一次resume;当with*Continuation操作返回时,不需要精确地调用

    2.2K10

    GCD梳理与总结-常用API操练

    延时执行(dispatch_after) 需要注意是:dispatch_after函数并不是指定时间之后才开始执行处理,而是指定时间之后将任务追加到队列。...%@",[NSThread currentThread]); });复制代码 只执行一次(dispatch_once) 通常在创建单例时使用,多线程环境下也能保证线程安全 static dispatch_once_t...dispatch_apply按照指定次数将指定任务追加到指定队列等待全部队列执行结束。你可以把他理解成for循环遍历,其优势是可以充分利用多核性能。...挂起(dispatch_suspend)、恢复(dispatch_resume)队列 简单来说,就是可以暂停、恢复队列上任务。...但是这里挂起”,并不能保证可以立即停止队列上正在运行任务,也就是如果挂起之前已经有队列任务进行,那么该任务依然会被执行完毕 //串行队列 dispatch_queue_t queue =

    35352

    Delphi异常机制与SEH

    SEH提供了两种方式供开发者使用,一种是线程,通过设置线程SEH链表结构。...当MOV [EBX], 0发生内存访问错后,系统挂起,查找SEH处理链表,通知ExceptionHandler进行处理,ExceptionHandler,将EBX修复到一个可以访问内存位置,再通知系统恢复环境继续执行...VCL对SEH封装 Delphi里我们通常使用try except end 和 try finally end 来处理异常,那么VCL里是怎么来实现呢?...1 、 VCL 顶层异常捕获 DELPHI开发程序,出错时候,我们很少看到出现一个错误对话框,提示点确定结束程序,点取消调试。而在VC或VB里就很常见,这是为什么呢?...4 、 VCL 对象构造时异常处理 Delphi开发时候,经常会重载构造函数constractor,构造函数是创造对象过程,如果这个时候出现异常VCL会怎么办呢?

    1.2K10

    Lua连续教程之Lua线程和状态

    从C API角度来看,把线程当作一个栈会比较有用;而从实现角度来看,栈实际上就是线程。每个站都保存着一个线程挂起函数调用信息,外加每个函数调用参数和局部变量。...使用多线程主要目的是实现协程,从而可以挂起某些协程执行,并在之后恢复执行。...最后,如果正在运行哈数被挂起,lua_resume就会返回代码LUA_YIELD,并将线程置于一个可以后续再恢复执行状态。...要恢复一个挂起线程,可以再次调用lua_resume。在这种调用,Lua假设栈中所有的值都会被调用yield返回。...我们实现,每个状态都将其对应Proc结构体作为完整用户数据存储注册表,关联键为”_SELF”。

    3.2K20

    使用kotlin协程提高app性能(译)

    Android上,协程有助于解决两个主要问题: 管理长时间运行任务,否则可能会阻止主线程导致应用冻结。 提供主安全性,或从主线程安全地调用网络或磁盘操作。...在上面的示例,get()仍然线程上运行,但它在启动网络请求之前挂起协同程序。当网络请求完成时,get恢复暂停协程,而不是使用回调来通知主线程。...一个做法是使用withContext()来确保每个函数都是主安全,这意味着您可以从主线程调用该函数。 这样,调用者永远不需要考虑应该使用哪个线程来执行该函数。...在前面的示例,fetchDocs()线程上执行; 但是,它可以安全地调用get,后者在后台执行网络请求。...某些情况下,Kotlin协程可能会在暂停和恢复后将执行移动到另一个线程。 这意味着线程局部变量可能不会指向整个withContext()块相同值。

    2.3K10

    LockSupport秘籍:新手入门,高手精通,玩转同步控制

    它是一个非阻塞性挂起操作,不会释放任何锁资源。因此,通常与 java.util.concurrent.locks 包锁一起使用。...实际应用,可以将park()放在一个循环中,并在循环条件检查中断状态。...底层阻塞和解除阻塞操作是通过 Unsafe 类来实现,这是一个提供低级别、非安全、操作系统级别访问类。...七、 注意事项 当使用 LockSupport.park() 挂起线程时,应该确保有一个明确机制来恢复(通过 unpark())或中断线程,以避免线程永久挂起。...答案: LockSupport park 和 unpark 方法是通过底层 Unsafe 类来实现,这是一个提供低级别、非安全、操作系统级别访问类。

    15710

    kotlin 协程入门教程

    除此之外,当其中一个线程没有任务时,kotlin线程池则会尝试分发其他线程任务给空闲线程。至于这么做有什么好处,官方给答案是以最有效方式工作线程上分发已调度任务。...至于 挂起函数 通过挂起恢复解决了开发过程回调地狱问题。而结构化并发 则可以对一组协程进行统一操作。关于它们详细介绍,可以继续往下面看。...另外两个则使用得比较少 block 是指带接收者挂起函数,是 kotlin 语法糖,它其实等同于suspend CoroutineScope(self: CoroutineScope) -> Unit...挂起函数 挂起函数是指方法声明前加上 suspend 关键字函数。它作用主要是挂起恢复。其实说挂起恢复比较难理解,其实简单挂起就是协程任务从当前线程脱离,恢复则是协程任务回到了原线程。...它也是通过 Job 来实现。不同于java多线程kotlin 协程,有父子协程概念。

    19710

    Android面试官问协程,你会如何选择应对这些高级问题?

    出发点:主要考察协程概念以及与线程相比优势。 参考简答:协程是一种轻量级线程,它在执行时可以被挂起恢复,并且不需要占用额外线程资源。...与线程相比,协程更加轻便,能够遇到阻塞操作时主动释放线程而不是一直等待。 协程优势包括: 资源节约: 协程可以一个线程运行,避免了线程切换开销,同时能够更好地利用系统资源。...协程工作原理与调度器 问题: 请解释协程工作原理,并说明协程是如何进行调度。 出发点: 说明挂起恢复机制,以及协程调度器作用。 参考简答:协程工作原理基于挂起恢复。...协程取消与异常处理 问题: 如何正确处理协程取消操作,解释协程异常处理机制?...适用场景: 大量并发任务情况下,使用协程池可以避免创建过多线程,提高性能。 协程线程安全性 问题: 如何确保协程数据操作是线程安全协程中有哪些工具可以使用?

    36210

    它是线程吗?

    内存模型 2.1 线程内存模型 JVM,每个线程都有自己独立线程栈,每个栈帧包含局部变量、操作数栈和相关信息。当线程挂起时,所有这些信息必须保存并在重新调度时恢复。...2.2 协程内存模型 协程栈帧通常是堆上对象,当协程挂起时,不需要切换线程,只是函数调用的上下文发生变化,把协程状态保存到堆。这种模型使得内存利用更加高效和灵活。...2.3 协程堆栈帧 协程挂起时,会将当前堆栈帧转换为对象并存储。这个对象包含了所有当前帧局部变量、挂起点以及其他必要信息。恢复时,这个对象重新转换为堆栈帧继续执行。...3.2 协程 协程仅占用一个线程部分时间,是由协程库(例如 kotlinx.coroutines)管理。一个线程可以执行多个协程,只要它们异步工作时常挂起恢复。这大大减少了切换开销,改善性能。...这是因为: 非阻塞挂起: delay 使得协程挂起,但不阻塞线程,使得同一线程可以继续处理其他协程。 上下文保存和恢复: 协程上下文切换只需要保存和恢复堆上对象状态,代价低。

    8410

    sdfsdfsd_dsd cd

    ,无需此步骤 分发客户端软件只需一个文件:你客户端程序 服务器和客户端无需Midas.dll,也不需要注册regsvr32 Midas.dll,看来Delphi2010datasnap抛弃使用COM...Session 说明:这是delphi2010默认属性,也是delphi推荐设置。Session会为每个来自客户端链接,建立一个线程来实例化。实例化是什么概念呢?...Invocation 说明:服务器只是建立连接,但是先不做实例化,只有当客户端请求功能时候,服务器才开线程实例化,当客户端用完后,服务器就释放线程和实例。 适用环境:这个设置是线程安全!...Server 说明:服务器对所有客户端连接使用一个实例,不是线程安全。所以要自己控制客户端并发调用问题(可以使用互斥、原子量等方法),让客户端调用排成一队使用服务器资源。...适用环境:这个设置不是线程安全!!

    2K10

    python 可迭代对象 迭代器 生成器_Python3迭代器获取

    return 执行返回值后,便会直接退出函数体,该函数内存空间即回收释放 yield执行返回值后,不会退出函数体,而是挂起,待下次next时,再从挂起恢复运行 yield语句可以接受通过生成器send...方法传入参数赋值给一个变量,以动态调整生成器行为表现 yield语句返回值,可以通过from 关键词指定 返回源 return在生成器作用: 一个生成器函数,如果没有 return,则默认执行至函数完毕...它被包含在进程之中,是进程实际运作单位 协程可以认为是一个线程内运行代码 进程包含线程线程包含协程 进程、线程切换和调度,一般由操作系统自动完成,具体调度和切换机制较为复杂 同一线程下,多个协程切换是由自己编写代码进行控制...:不需要线程锁机制,因为只有一个线程,也不存在同时写变量冲突,协程控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多 协程借助生成器实现基本思路: 因为生成器通过yield,...可以挂起,待下次执行时再次从挂起恢复运行,满足切换和交替运行特点 因为生成器可以通过send函数,动态干预指定生成器功能和表现,为实现多个协程之间协作提供了可能 下面代码简单举例用生成器实现协程机制

    1K20

    block与GCD--43:NSOperation 与NSOperationQueue

    这些操作(包括 blockOperationWithBlock 操作)可以不同线程同时(并发)执行 只要NSBlockOperation封装操作数大于1,就会异步执行 注: 如果添加操作多的话...,blockOperationWithBlock: 操作也可能会在其他线程(非当前线程执行,这是由系统决定,并不是说添加到 blockOperationWithBlock: 操作一定会在当前线程执行...用来控制一个特定队列可以有多少个操作同时参与并发执行 这里 maxConcurrentOperationCount 控制不是并发线程数量,而是一个队列同时能并发执行最大操作数。...而且一个操作也并非只能在一个线程运行 maxConcurrentOperationCount 默认情况下为-1,表示不进行限制,可进行并发执行。...当队列调用了队列挂起方法( self.queue.suspended = YES),队列里执行方法立即停止,但是有一点需要注意是,当block操作,队列挂起是不起作用,它是无法停止,必须操作执行结束后才会生效

    13810

    Swift异步编程方式

    需要注意,异步和并行本身是两个概念,Swift,异步编程模型已经建立在线程调度之上,这也就是说,我们无需关心其中线程调用,异步函数本身就是线程并行执行线程切换和调度全有语言本身控制。...需要注意,理论上异步函数是不允许使用Thread相关接口,因为任务挂起恢复所在线程都是由系统调度,逻辑上开发者无需关心线程问题,Swift6版本中继续这样使用将会报错。...,此时会停止当前线程上代码执行,等待异步函数返回,程序,支持await进行挂起场景包括: 1.异步方法,属性或函数。...这非常有用,有时我们需要在非并发环境调用异步函数,例如在iOS ApplicationViewControllerviewDidLoad方法调用一个异步函数,此时就需要为其包装一个并发环境,...,线程资源会被释放去执行其他任务,直到异步任务有结果后,恢复执行。

    41210

    PEP 255--简单生成器

    或者想象一下,用递归算法来生成普通树结构节点:若把它投射成一个迭代器框架实现,就需要手动地移除递归状态维护遍历状态。 第四种选择是不同线程运行生产者和消费者。...但是从调用者角度来看,fib 调用就是一个可随时恢复可迭代对象。跟线程一样,这允许两边以最自然方式进行编码;但与线程方法不同,这可以在所有平台上高效完成。...在数百条消息,我算了每种替代方案有三条建议,然后总结出上面这些。不需要用新关键字会很好,但使用 yield 会更好——我个人认为,一堆无意义关键字或运算符序列,yield 更具表现力。... Icon ,return expr 意味着“我已经完成”和“但我还有最后一个有用值可以返回,这就是它”。...但是,就像希腊神话 Delphi(译注:特尔斐,希腊古都) 甲骨文一样,它并没有告诉我原因,所以我没有对反对此 PEP 语法论点进行反驳。

    57520

    透过 Rust 探索系统本原:并发原语

    // **4 result } } 这段代码是编译不过,因为按照 Rust 借用规则,T 不能安全多个线程间存在可变引用。...你可以用 fetch_add 来增加这个 id,而 fetch_add 返回结果就可以用于当前 id。这样,我们不需要加锁,就得到了一个可以线程安全使用 id 生成器。...更通用解决方案是:当多个线程竞争同一个 Mutex 时,获得锁线程得到临界区访问,其它线程会被挂起,放入该 Mutex 上一个等待队列。...当然,这样实现会带来公平性问题:如果新来线程恰巧 spin 过程拿到了锁,而当前等待队列还有其它线程等待锁,那么等待线程只能继续等待下去,这不符合 FIFO,不适合那些需要严格按先来后到排队使用场景...当 channel 里没有数据可读时,读者会挂起(block),而写者写入新数据时,需要通知读者恢复运行。这个过程,我们需要通过 Condvar 来实现。

    1.1K20

    结构化并发

    类似地,当一个函数从某个async调用返回,调用者相同任务恢复运行。 同步函数没有必要作为任务一部分运行。 Swift 认为存在一个底层线程系统。系统调度任务运行在这些线程系统上。...任务不需要从底层线程系统获取特殊调度支持,尽管一个调度者可以利用 Swift 任务调度一些有趣特性。...该任务会一直运行,直到从它初始化函数返回(完成状态),又或者到达一个挂起点(挂起暂停状态)。挂起点,如果该任务执行只需要改变参与者,那么它可能会立即变得可调度。...异步函数作为任务一部分运行,如果任务正在运行,任务和它当前函数也都运行在一个线程; 注意,当一个异步函数调用另一个异步函数时,我们任务正在调用函数是挂起状态,但并不意味整个任务是挂起状态。...传给Task闭包会立即执行,对self唯一引用是函数体中发生内容。因此,Task中使用显式self.没有传达有用信息,不需要使用。

    3K40

    【Kotlin 协程】Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | Android 中使用 Flow 异步流下载文件 )

    , 通过调用 FlowCollector#emit 生成一个元素 ; 函数原型如下 : /** * [FlowCollector]用作流中间或终端收集器,表示接收[Flow]发出实体。...* 该接口通常不应该直接实现,而是实现自定义操作符时作为[flow]构建器接收器使用。 * 这个接口实现不是线程安全。...挂起 500ms // 协程, 该挂起操作不会阻塞调用线程, 会继续执行其它代码指令 // 500ms 恢复执行, 继续执行挂起函数之后后续代码指令...// 500ms 恢复执行, 继续执行挂起函数之后后续代码指令 delay(500) // 每隔 500ms 产生一个元素 //...// 挂起函数 挂起 500ms // 协程, 该挂起操作不会阻塞调用线程, 会继续执行其它代码指令 // 500ms 恢复执行, 继续执行挂起函数之后后续代码指令

    1.5K11
    领券