gpt4 book ai didi

c - Scintilla 和线程安全

转载 作者:太空宇宙 更新时间:2023-11-04 07:42:30 24 4
gpt4 key购买 nike

我在 Windows(Win32、C/C++)上使用 Scintilla 编辑控件。该控件是在 WndProc 中创建的。我有第二个线程,使用 Boost.Thread 创建,它充当拼写检查器并用红色波浪线标记拼写错误的单词。因此,我有两个线程更改 Scintilla 控件的内容。

起初,程序在编辑文本时崩溃。所以我研究了 Scintilla 的线程安全性。我发现的信息很少,但我设法在文档中引用了这句话:

direct calling will cause problems if performed from a different thread to the native thread of the Scintilla window in which case SendMessage(hSciWnd, SCI_*, wParam, lParam) should be used to synchronize with the window's thread.

当然,我使用的是直接调用,因此我将拼写检查线程中的所有调用更改为 SendMessage,现在程序不会再崩溃了。最后,这就是问题,我是否解决了问题,或者我是否会遇到 Scintilla 和多线程的其他怪癖?

最佳答案

您通常应该只从创建它们的线程访问 Windows 中的窗口(HWND)。发送到窗口的任何消息都将在创建它的线程中执行,这就是崩溃的原因当您通过发送消息替换对 Scintilla 函数的所有直接调用时,这种情况就停止了。如果您在拼写检查线程中使用 SendMessage(),这将导致发生以下情况:

  • 拼写检查线程将阻塞
  • 将执行到 GUI 线程的上下文切换
  • 消息循环将处理该消息(但不一定立即处理,队列中的消息将按照它们添加的顺序进行处理,因此只有在处理完所有先前添加的消息后才会处理该消息)
  • 将执行到拼写检查线程的上下文切换
  • SendMessage() 调用返回结果

所以你确实解决了这个问题,但是付出了很高的代价。每个拼错的单词都会导致两次线程上下文切换,拼写检查会因每个拼错的单词而阻塞。如果需要很长时间处理的任何其他消息仍在排队,这实际上可能会花费很长时间。

您应该更改程序的设计。理想情况下,两个线程都能够独立工作,这可以通过添加一个线程安全的数据结构来实现,拼写检查线程将有关拼写错误的单词的信息添加到该数据结构中,主线程从中检索信息。 Boost 有很多类可以帮助你。通过这样做,您可以继续使用直接调用,因为它们将在主线程的上下文中执行。性能应该会提高,因为多个单词可能会被一次性加下划线,从而只导致一次控件重绘。如果您使用 PostMessage() 而不是 SendMessage(),拼写检查线程将能够独立于主线程准备好处理消息继续其工作。

如果您记得永远不要从辅助线程调用任何 Scintilla 代码,您就不会遇到其他怪癖。这并不是 Scintilla 控件所特有的,调用内部不使用 Windows 消息的 Windows API 函数对于任何其他控件也会有问题。

关于c - Scintilla 和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2367633/

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