我知道 XInitThreads()
将允许我从主线程以外的线程调用 X 服务器,如果我想制作 OpenGL calls from secondary threads using Qt ,则 Xlib 中的并发线程支持是必要的。我对我的申请有这样的需求,但在非常罕见的情况下。不幸的是,XInitThreads() 需要在我的应用程序执行的一开始就被调用,因此无论我是否需要它来进行特定的运行都会影响它(如果我确实需要多线程 OpenGL,在运行应用程序之前我无法知道)支持与否)。
我很确定,如果我无用地调用 XInitThread(),应用程序的整体行为将保持不变,但编程就是权衡,我很确定多线程支持不是 Xlib 的默认行为是有原因的。
The man page 说建议单线程程序不要调用这个函数,但是没有说为什么。调用 XInitThreads() 时的权衡是什么?
最佳答案
它创建一个全局锁,并且在每个显示器上也创建一个,因此每次调用 Xlib 都会执行锁定/解锁。如果您改为使用自己的锁定(使用自己的锁将 Xlib 使用一次保留在一个线程中),那么理论上您可以通过获取您的锁,一次执行大量 Xlib 操作,然后删除来减少锁定开销你的锁。或者在实践中,大多数工具包使用的模型根本不锁定,而只要求应用程序仅在主 UI 线程中使用 X。
由于许多 Xlib 调用被阻塞(它们等待来自服务器的回复)锁争用可能是一个问题。
在 Display 上锁定每个 Xlib 调用也有一些语义上的痛苦;在线程 A 上的每个 Xlib 调用之间,理论上任何其他 Xlib 调用都可以在线程 B 上进行。因此线程可以在混淆显示状态方面相互踩踏,即使一次只有其中一个发出 Xlib 请求.也就是说,XInitThreads() 正在防止由于并发 Display 访问而导致的崩溃/损坏,但它并没有真正考虑让多个线程共享一个 X 服务器连接的任何语义考虑。
我认为需要从并发显示访问中获得自己的语义意义是人们不打扰 XInitThreads per-Xlib-call 锁定的原因之一。因为无论如何它们最终都会获得应用程序级别或工具包级别的锁。
这里的一种方法是在每个线程中打开一个单独的 Display 连接,这取决于您在做什么。
另一种方法是使用较新的 xcb API 而不是 Xlib; xcb 从头开始设计为多线程和非阻塞。
从历史上看,在某些 OS/Xlib 版本中的 XInitThreads() 中也存在一些错误,尽管我不记得任何细节,但我确实记得看到这些错误。
关于multithreading - XInitThreads() 的缺点是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13351297/