Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > connect и типы


Автор: gpepsi 1.10.2011, 08:54
Использовал сигнал из потока. Обработчик слота находился в другом потоке.
Заметил, что сигнал не доходит.

Поставил Qt::DirectConnection. Сигнал стал приходить.
Но читая про него обнаружил еще и Qt::BlockingQueuedConnection, про который было написано, что он предназначен для
работы из различных потоков и так же блокирует очередь. Но есть коментарий, что этот сигнал может привести
к deadlock-у.

Поставил Qt::BlockingQueuedConnection - вообще перестало приходить.

В чем тогда различае между ними, если оба блокируют, но только второй может зависнуть. 

Автор: bsa 3.10.2011, 00:44
Чтобы сигнал доходил, необходимо чтобы в потоке был EventLoop. Почитай про него в документации по QThread.

Автор: gpepsi 3.10.2011, 16:30
Цитата(bsa @  3.10.2011,  00:44 Найти цитируемый пост)
Чтобы сигнал доходил, необходимо чтобы в потоке был EventLoop. Почитай про него в документации по QThread. 


Код

You can start the event loop by calling exec(); you can stop it by calling exit() or quit().


но я не хочу вызывать exec(). Иначе я повисну на нем до окончания работы потока.
А я хочу запустить поток и перейти в первичный поток. А созданный пусть крутится и сигналит.

Автор: bsa 3.10.2011, 23:26
Попробуй добавить thread->moveToThread(thread); сразу после старта потока (в конструктор, например, наследника QThread).

Автор: gpepsi 4.10.2011, 08:14
Цитата(bsa @  3.10.2011,  23:26 Найти цитируемый пост)
Попробуй добавить thread->moveToThread(thread); сразу после старта потока (в конструктор, например, наследника QThread). 

а что это даст ?

Автор: bsa 5.10.2011, 13:58
gpepsi, а ты попробуй. может что-нибудь и даст...

Автор: gpepsi 23.10.2011, 11:45
Цитата(bsa @  5.10.2011,  13:58 Найти цитируемый пост)
gpepsi, а ты попробуй. может что-нибудь и даст... 

так и не могу понять принцип работы.
В слот добавил
Код

Q_ASSERT(QThread::currentThreadId() != qApp->thread()->currentThreadId());


что при moveToThread(this);, что без него отрабатывает assert. Сигнал - Qt::AutoConnection похоже == Qt::QueuedConnection - в этом причина ?

P.S. Я так понимаю, что QThread::exec запускает цикл обработки. Это нужно, чтоб доходили сигналы до потока. Тогда можно вызвать quit для 
завершения потока. А что если поток выполняет очень долгие расчеты (например несколько часов), то как тогда завершить поток ?
То есть как в потоковой функции проверять завершение потока, если до exec дело не дошло либо его вообще нет ?

P.P.S Или если вызывать quit, то в потоке нужно запустить exec. Как тогда построить код, чтоб потоковый объект обрабатывал сигналы и
мог выполнять долгие расчеты ?

Автор: Artemon 24.10.2011, 08:59
Цитата(gpepsi @  3.10.2011,  16:30 Найти цитируемый пост)
но я не хочу вызывать exec(). Иначе я повисну на нем до окончания работы потока.

Так в этом и есть суть обработки очереди сообщений. Ты сможешь потоку кидать сигналы и он соответственно сможет на них реагировать.
Здесь уж придется выбирать, либо с поддержкой сигналов, либо без нее, но при этом метод run не блокируется.

Автор: gpepsi 24.10.2011, 09:20
Цитата(Artemon @  24.10.2011,  08:59 Найти цитируемый пост)
Так в этом и есть суть обработки очереди сообщений. Ты сможешь потоку кидать сигналы и он соответственно сможет на них реагировать.Здесь уж придется выбирать, либо с поддержкой сигналов, либо без нее, но при этом метод run не блокируется.

если я буду поддерживать сигналы, то мне тогда достатточно просто создать объект в потоке и запустить цикл обработки потока ?
И слоты его тогда будут обрабатываться в отдельном потоке ?

Автор: Artemon 24.10.2011, 11:31
Да, должно быть именно так. Для этого нужно не забыть поставить последним параметром сетода connect константу Qt::QueuedConnection.

Вот цитата из переведенной документации Qt:

Цитата

С постановкой сигналов в очередь - слот выполняется, когда контроль возвращается в цикл обработки сообщений потока, которому принадлежит объект. Слот выполняется в потоке, в котором проживает объект-приемник.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)