LINUX.ORG.RU

[Qt, shared lib, threads, GUI] Всё вместе — отказывается корректно работать


0

0

Программа построена следующим образом: «пускалка» загружает в себя разделяемые библиотеки, и предоставляет им функции, в том числе и создания/удаления GUI-объектов. Если пытаться вызвать эти функции из потоков (QThread), в debug-сборке выкидывает ошибку runtime (src/corelib/thread/qthread_%OS%.cpp) на следующей строке:

void *QThreadPrivate::start(void *arg)
{
    // Symbian Open C supports neither thread cancellation nor cleanup_push.
#ifndef Q_OS_SYMBIAN
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
    pthread_cleanup_push(QThreadPrivate::finish, arg);
#endif

    QThread *thr = reinterpret_cast<QThread *>(arg);
    QThreadData *data = QThreadData::get2(thr);// !!! Здесь, в get2, ошибка runtime !!!

Если же собирать в release, то ограничивается сообщением в консоли.

Вопрос: есть ли возможность задавить это поведение, или как обойти его?

Из потоков нельзя гуём управлять, насколько я помню. А вообще, мне кажется, что в твоём сообщении не хватает примера кода, на котором проявляется проблема.

name_no ★★
()

GUI-классы в Qt не thread-safe и даже не reentrant, использовать их можно только из основного потока. В функциях, которыми управляется GUI из библиотек, проверяйте, если текущий поток основной

if ( QThread::currentThread() == QCoreApplication::instance()->thread() )

, то вызывайте методы прямо из этой самой функции, иначе - дёргайте из через обёртку вроде:

QMetaObject::invokeMethod( myGuiManipulator, "doSomethingWithGui", Qt::BlockingQueuedConnection, Q_ARG(MyType,myValue) );

При этом функция MyGuiManipulator::doSomethingWithGui( MyType myValue ) будет вызвана из основного потока, а поток библиотеки подождёт её завершения.

Dendy ★★★★★
()
Ответ на: комментарий от name_no

> не хватает примера кода, на котором проявляется проблема

Да там здоровая простыня получится, хоть это, пока ещё, и «скелет». А если «своими словами» — то динамической библиотеке передаётся интерфейс «ядра», в котором есть функции создания гуёвых объектов. Пока эти функции дёргаются непосредственно из кода библиотеки, всё в порядке. Но при попытке вызвать их из потока, созданного в той же библиотеке — проблемы.

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

> Но при попытке вызвать их из потока, созданного в той же библиотеке — проблемы.

Ну тогда смотри второй комментарий в теме. Дёргать гуй из потоков нельзя, это написано в документации к Qt.

name_no ★★
()
Ответ на: комментарий от name_no

> Дёргать гуй из потоков нельзя, это написано в документации к Qt

Да знаю, что официально нельзя, но очень нужно, потому и спросил. :-)

one_more_hokum ★★★
() автор топика
Ответ на: комментарий от one_more_hokum

Для передачи управления бросай сигнал в потоке и лови его в gui-потоке. Только так можно и никак иначе.

Reset ★★★★★
()
Ответ на: комментарий от one_more_hokum

> но очень нужно

1. Обоснуй в студию.
2. Что за детский сад?

LamerOk ★★★★★
()
Ответ на: комментарий от one_more_hokum

>>Да знаю, что официально нельзя, но очень нужно, потому и спросил. :-)

В чем заключается такая необходимость? Используй сигналы.

MuZHiK-2 ★★★★
()
Ответ на: комментарий от MuZHiK-2

> Используй сигналы.

Уже решил так делать, подумав. Но и вариант с QMetaObject::invokeMethod тоже интересен, поковыряю его.

one_more_hokum ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.