XInitThreads()的缺点是什么?

Fre*_*red 4 x11 qt multithreading

我知道XInitThreads()将允许我从主线程以外的线程调用X服务器,如果我想使用Qt从辅助线程进行OpenGL调用,那么Xlib中的并发线程支持是必要的.我对我的应用程序有这样的需求,但是在非常罕见的情况下.不幸的是,XInitThreads()需要在应用程序执行的最初阶段调用,因此对于特定的运行是否需要它会影响它(如果我需要多线程OpenGL,我在运行应用程序之前无法知道)支持与否).

我很确定如果我无用地调用XInitThread(),应用程序将保持不变的整体行为,但编程完全是权衡,我很确定多线程支持不是Xlib的默认行为.

该手册页说,建议单线程程序不要调用此函数,但它没有说明原因.调用XInitThreads()时的权衡是什么?

Hav*_*c P 13

它创建了一个全局锁,每个显示器上也有一个锁,因此每次调用Xlib都会进行锁定/解锁.如果您改为自己进行锁定(使用自己的锁保持Xlib一次使用在一个线程中),那么理论上你可以通过锁定,一次执行大量Xlib内容然后丢弃来减少锁定开销.你的锁.或者在实践中,大多数工具包使用的模型根本不会锁定,只需要应用程序仅在主UI线程中使用X.

由于许多Xlib调用都是阻塞的(它们等待来自服务器的回复),因此锁争用可能是一个问题.

在Display上锁定per-Xlib-call也会有一些语义上的痛苦; 在线程A上的每个Xlib调用之间,理论上任何其他Xlib调用都可以在线程B上进行.因此线程可以在混淆显示状态方面相互踩踏,即使其中只有一个一次发出Xlib请求.也就是说,XInitThreads()可以防止由于并发显示访问而导致的崩溃/损坏,但它并没有真正处理让多个线程共享X服务器连接的任何语义考虑因素.

我认为需要通过并发显示访问来创建自己的语义感,这是人们不会为XInitThreads per-Xlib-call锁定而烦恼的一个原因.因为无论如何它们最终会得到应用程序级别或工具包级别的锁定.

这里的一种方法是在每个线程中打开一个单独的Display连接,这可能是有意义的,具体取决于您正在做什么.

另一种方法是使用较新的xcb API而不是Xlib; xcb从头开始设计为多线程和非阻塞.

从历史上看,在某些OS/Xlib版本中,XInitThreads()中也存在一些错误,但我不记得任何细节,我记得看到过那些错误.