Проблемы с потоками Qt в Linux

Я развиваюсь с Qt в течение некоторого времени в моем проекте, и мы начинаем двигаться к более ориентированному на поток дизайну. При перемещении некоторых виджетов GL-рендеринга в другие потоки я обнаружил очень странное поведение. Похоже, что если GL Widget начинает обновление из другого потока (boost thread или QThread) до того, как виджет, который принимает ввод пользователя (например, QTextEdit), захватит фокус, я получаю сбои 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]

Если я добавлю строку 'mdiArea.addSubWindow(новый QTextEdit (this)); на линии 313 (до вызова функции newThread()), тогда при запуске демо-версии появится QTextEdit и виджет Hypnotizer GL. Если я затем нажму на QTextEdit, чтобы захватить фокус, я получаю вышеупомянутый сбой каждый раз.

Может ли кто-нибудь воспроизвести ошибку при установке Linux с помощью вышеуказанных инструкций? Кто-нибудь сталкивался с этими типами проблем в Linux с использованием Qt и потоковой передачи до?

Примечание. Я использую Ubuntu 12, и этот сбой происходит в установках VirtualBox и без VirtualBox Ubuntu.

Ответ 1

OpenGL, рендеринг Qt и многопоточность не очень хорошо смешиваются. В частности, контекст OpenGL может быть активен только в одном потоке за раз. Теперь, если контекст распределяется между несколькими виджетами (обратите внимание, что это отличается от совместного использования объектов между контекстами, я говорю об одном контексте, который используется для нескольких окон/виджетов, который является законным), и эти виджеты, отображаемые из разных потоков, которые вы собираетесь для решения многих проблем.

Обычно лучший способ действий OpenGL и многопоточности - это не делать этого. Используйте несколько потоков, да, но используйте их для всего, что не связано с OpenGL или любым графическим выходом. Храните все графические операции в одном потоке, чтобы избежать серьезных проблем.