2.3 图形的线程问题

不同的窗口系统对多线程有不同的限制,这对 HALCON 图形算子有影响。

2.3.1 微软 Windows

在微软 Windows 中,只有在创建窗口的线程中才能访问窗口的消息队列。此外,有父窗口的窗口必须在创建父窗口的线程中打开。

所有 HALCON 图形算子都会自动重定向到正确的线程。这是通过向窗口发送一条特殊消息来实现的。为避免与用户代码发生冲突,该消息的 ID 是使用 Win32 RegisterWindowMessage 函数动态生成的。对于非 HALCON 创建的窗口(这与 new_extern_window 以及为 open_window 指定父窗口相关),非 HALCON 窗口会使用 Win32 SetWindowSubclass 函数自动子类化。对用户代码的唯一要求是,要使这一机制发挥作用,每个窗口都必须有一个活动的消息循环。

为了避免编写用户代码来处理 HALCON 窗口的消息循环,可以指示 HALCON 通过 set_system('use_window_thread','true') 从一个特殊线程创建所有顶级 HALCON 窗口,这样也可以处理消息循环。请注意,如果同时使用多个窗口,这可能会对性能产生负面影响,因为 HALCON 只为所有窗口提供一个线程。

各种 HALCON draw_* 算子通过主动轮询消息队列来工作。如果多个 draw_* 算子的目标窗口属于不同的线程,则这些算子可以处于活动状态。

2.3.2 X11

在使用 X11 窗口系统时,HALCON 会在打开第一个窗口时自动调用 Xlib 函数 XInitThreads(注意,查询可用的 OpenGL 功能将在后台打开一个隐藏的 X11 窗口)。

这意味着,如果使用 HALCON 的应用程序也使用了独立于 HALCON 的 Xlib 函数,无论是直接显式调用 Xlib 函数,还是通过使用 Xlib 的其他库间接调用,都必须注意在调用其他 Xlib 函数之前首先调用 XInitLibrary。确保这一点的最简单方法是在应用程序的主函数中尽早调用 XInitThreads,然后再调用任何其他库函数。