我已经在Qt上开发了一段时间用于我的项目,我们开始转向更加面向线程的设计。在将一些GL渲染小部件移动到其他线程后,我发现了一些非常奇怪的行为。看来如果GL Widget在接受用户输入的窗口小部件(例如QTextEdit)抓取焦点之前从另一个线程(boost线程或QThread)开始更新,我会看到XCB崩溃,如下所示:
[xcb] Too much data requested from _XRead
[xcb] This is most likely caused by a broken X extension library
[xcb] Aborting, sorry about that.
hypnotizer: ../../src/xcb_io.c:735: _XRead: Assertion ‘!xcb_xlib_too_much_data_requested’ failed.
为了测试这一点,我实际上可以对GLHypnotizer演示进行简单的修改以重现崩溃。该演示可以在这里找到:http://qt-project.org/doc/qt-4.8/demos-glhypnotizer.html [qt-project.org]
如果我在第313行(在调用newThread()之前)添加'mdiArea.addSubWindow(new QTextEdit(this));',那么当演示开始时会有一个QTextEdit和一个GL Hypnotizer Widget 。如果我然后单击QTextEdit以获得焦点,我每次都会遇到上述崩溃。
有人可以使用上述说明在Linux安装上重现错误吗?有没有人在使用Qt和线程之前在Linux上遇到过这类问题?
注意:我使用的是Ubuntu 12,这种崩溃发生在VirtualBox和非VirtualBox Ubuntu安装中
答案 0 :(得分:2)
OpenGL,Qt渲染和多线程不能很好地混合。特别是OpenGL上下文一次只能在一个线程中激活。现在,如果上下文在多个小部件之间共享(请注意,这与上下文之间共享对象不同,我说的是用于多个合法的多个窗口/窗口小部件的单个上下文),并且这些窗口小部件从不同的线程呈现,你要去进入很多问题。
对于OpenGL和多线程而言,通常最好的做法是,而不是这样做。使用多个线程,是的,但是将它们用于与OpenGL或任何类型的图形输出无关的所有内容。将所有图形操作保留在一个线程中,以避免出现重大问题。