线程同步问题的困惑

发布于 2024-08-18 11:40:15 字数 747 浏览 2 评论 0原文

今天读Zarko Gajic的文章时让我很困惑:

多线程Delphi数据库查询

文章网址:http://delphi.about.com/od/kbthread/a/query_threading.htm

源代码:http://delphi.about.com/library/weekly/code/adothreading.zip

与“TCalcThread.Execute”程序的代码,为什么下面的代码不需要放在Synchronize()方法中运行呢?

Line 173:    ListBox.Clear;  
Line 179:    ListBox.Items.Insert(......);
Line 188:    ListBox.Items.Add('*---------*');
Line 195:    TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks);

这些代码操作VCL组件,与UI更新相关。据我所知,这些操作应该使用线程同步,并由主线程执行。难道是我的知识有缺陷?

It makes me confused when I read the article by Zarko Gajic today:

"Multithreaded Delphi Database Queries"

Article URL: http://delphi.about.com/od/kbthread/a/query_threading.htm

Sourecode: http://delphi.about.com/library/weekly/code/adothreading.zip

With the code of "TCalcThread.Execute" procedure, Why the following code do not need to be placed in the Synchronize() method to run?

Line 173:    ListBox.Clear;  
Line 179:    ListBox.Items.Insert(......);
Line 188:    ListBox.Items.Add('*---------*');
Line 195:    TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks);

These codes are operating the VCL components, and are related to the UI updates. In my knowledge, these operations should be use thread synchronize, and executed by the main thread. Is my knowledge has the flaw?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千柳 2024-08-25 11:40:15

这是一种罕见的情况,您可以从 Windows 为您执行线程同步这一事实中受益。原因是对于列表框,项目是使用带有控制特定消息的 SendMessage 来操作的。因此,每个 SendMessage 调用都确保消息由创建控件的同一线程(尤其是主线程)处理。

正如我所说,这是一个罕见的案例。它还会导致这三个调用中的每一个调用都发生线程切换,这会降低性能。您最好还是使用 Synchronize 强制该代码块在其所属的主线程中运行。它还确保,如果您开始使用内部不使用 SendMessage 的控件,您不会被咬。

This is a rare case where you're benefiting from the fact that Windows is doing the thread synchronization for you. The reason is that for a listbox, the items are manipulated using SendMessage with control specific messages. Because of this, each SendMessage call makes sure the message is processed by the same thread on which the control was created, notably the main thread.

Like I said, this is a rare case. It is also causing a thread switch for each of those three calls, which will degrade performance. You're still better off using Synchronize to force that block of code to run in the main thread where it belongs. It also ensures that if you begin working with a control that doesn't internally use SendMessage, you won't get bitten.

半世蒼涼 2024-08-25 11:40:15

的确。也许示例没有问题,因为线程执行时没有 UI 更改。但 UI 事情总是必须发生在 UI 线程内。

我看到的同步和不同步指令之间的唯一区别是:

  • 不同步不是无参数方法,因此程序将更难以编写:)
  • 同步方法正在更新 TLabel它不是一个 TControl(如果我记得我的 Delphi 时代),所以它直接使用画布......

但无论如何:UI 是由单个线程触摸的。总是。有一次我想在线程内更新 TTreeBox(没有并行性也没有交叉更新,只是一个单独的线程),这是一件非常糟糕的事情(随机错误)......

Indeed. Maybe the sample isn't problematic cause there are no UI changes while the thread is executing. But UI things always have to occur inside the UI thread.

The only differences I see between the sync'ed and the not sync'ed instructions are:

  • the not sync'ed are not no-params methods so the program will be more dificult to write :)
  • the sync'ed method is updating a TLabel which is not a TControl (if I remember my Delphi days) so it uses canvas directly...

But anyway: UI is touched by a single thread. Always. Once I wanted to update a TTreeBox inside a thread (no paralelism nor cross updates, simply a separate thread) and it was a very bad thing (random errors)...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文