gpt4 book ai didi

multithreading - 使用 TThread.Resume 有什么问题?

转载 作者:行者123 更新时间:2023-12-03 14:37:14 25 4
gpt4 key购买 nike

很久以前,当我开始在 Delphi 中使用线程时,我通过调用 TThread.Resume 让线程自行启动。在其构造函数的末尾,并且仍然这样做,如下所示:

constructor TMyThread.Create(const ASomeParam: String);
begin
inherited Create(True);
try
FSomeParam:= ASomeParam;
//Initialize some stuff here...
finally
Resume;
end;
end;

从那时起,Resume已被弃用,转而使用 Start反而。然而,Start只能从线程外部调用,不能从构造函数内部调用。

我继续使用 Resume 设计我的线程如上所示,尽管我知道它已被弃用 - 只是因为我不想调用 Start从线程外部。我发现必须调用有点困惑:

FMyThread := TMyThread.Create(SomeParamValue);
FMyThread.Start;

问题:进行此更改的原因是什么?我的意思是,使用 Resume 有什么问题吗?他们希望我们使用 Start相反?

编辑在 Sedat 回答之后,我想这实际上取决于构造函数中线程何时实际开始执行。

最佳答案

简短而精辟的答案是因为 TThread 类的作者不信任开发人员阅读或理解文档。 :)

挂起和恢复线程仅在极少数用例中是合法的操作。事实上,这个有限的数量本质上是“一个”:调试器

不良情况

它被认为是不可取的(至少可以这么说)的原因是,如果线程被挂起,而(例如)它拥有某个其他同步对象(例如互斥体或信号量等)的锁,则可能会出现问题。

这些同步对象专门设计用于确保线程相对于访问共享资源的其他线程的安全操作,因此中断和干扰这些机制可能会导致问题。

调试器需要一种工具来直接挂起线程,而不管这些机制出于令人惊讶的相似原因。

例如,考虑断点涉及线程上的隐式(或者您甚至可以说ex显式)“挂起”操作。如果调试器在达到断点时暂停线程,那么它还必须暂停进程中的所有其他线程,因为否则它们将抢先执行可能会干扰调试器可能要求执行的许多低级任务的工作然后做。

调试器的强大力量

调试器无法“注入(inject)”良好的、礼貌的同步对象和机制来请求这些其他线程以与已被粗暴地停止(通过断点)的其他线程协调的方式挂起自己。调试器别无选择,只能强制线程,而这正是挂起/恢复 API 的用途。

它们适用于您需要停止线程的情况“现在。无论您在做什么,我不在乎,只要停止!”。然后,然后说“好吧,你现在可以继续之前所做的事情,无论它是什么。”。

行为良好的线程彼此之间表现良好

很明显,这不是行为良好的线程在正常操作中与其他线程交互的方式(如果它希望维持“正常”操作状态并且不创建所有类型的线程)的问题)。在这些正常情况下,线程非常确实并且应该关心其他线程正在做什么,并确保它不会干扰,使用适当的同步技术来协调那些其他线程。

在这些情况下,恢复线程的合法用例同样会简化为一种单一模式。也就是说,您创建并初始化了一个线程,您不希望立即运行该线程,而是希望在稍后的某个时间点在其他线程的控制下开始执行。

但是,一旦新线程已经启动,随后的与其他线程的同步必须使用这些正确的同步技术来实现,而不是暂停它的力量。

开始与暂停/恢复

因此,我们决定 Suspend/Resume 在通用线程类上没有真正的位置(实现调试器的人们仍然可以直接调用 Windows API),而是使用提供了更合适的“启动”机制。

希望大家能够清楚地看到,尽管此Start机制采用与之前已弃用的 Resume 方法完全相同的 API,但其目的却截然不同。

关于multithreading - 使用 TThread.Resume 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36000166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com