Russian Qt Forum
Ноябрь 23, 2024, 23:28
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Общие вопросы
>
Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
Страниц: [
1
]
2
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection? (Прочитано 10575 раз)
Akon
Гость
Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
:
Сентябрь 01, 2011, 16:51 »
сабж
Записан
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #1 :
Сентябрь 01, 2011, 19:38 »
рассоединить и соединить с Qt::DirectConnection ?
а что за юзкейс, позвольте полюбопытсвовать?
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #2 :
Сентябрь 01, 2011, 19:58 »
Из потока прут данные с уведомление по сигналу. Обработка производится синхронно (Qt::DirectConnection) пользовательским объектом, "живущим" в другом потоке. Если опустить параметр соединения, то для данного случая получится Qt::QueudConnection. Задача: предупредить пользователя (выдать диагностическое сообщение), если он подключится без Qt::DirectConnection (т.е. явно его не укажет).
Записан
LisandreL
Птица говорун
Offline
Сообщений: 984
Надо улыбаться
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #3 :
Сентябрь 01, 2011, 20:31 »
В слоте сравнить sender()->thread() c QThread::currentThread(), на всякий случай проверив sender() на 0.
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #4 :
Сентябрь 01, 2011, 21:05 »
sender()->thread() - дает поток, в котором объект "живет"; а сигнал объекта может быть испущен из любого другого потока, и sender()->thread() будет тем же самым.
Записан
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #5 :
Сентябрь 01, 2011, 22:17 »
ну, вот и правильно. как Вы выше указали, sender() в днном случае - это поток, из которого "прут данные".
если sender()->thread() == QThread::currentThread() /* равносильно qobject_cast<QThread *>(sender()) == QThread::currentThread() */, значит Qt::DirectConnection; иначе ругаемся
но всё-равно этот юз-кейс какой-то странный...ни разу за свою практику мне не приходилось делать подобных проверок.
и, кстати, в случае неосмотрительности при синхронизации потоков рискуете получить по ушам) я бы советовал использовать здесь Qt::QueuedBlockedConnection /* либо пересмотреть архитектуру приложения */
«
Последнее редактирование: Сентябрь 01, 2011, 22:19 от Константин
»
Записан
LisandreL
Птица говорун
Offline
Сообщений: 984
Надо улыбаться
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #6 :
Сентябрь 01, 2011, 22:32 »
Цитата: Константин от Сентябрь 01, 2011, 22:17
равносильно qobject_cast<QThread *>(sender()) == QThread::currentThread()
Щито?
sender() - это объект испустивший сигнал, он не обязан наследоваться от QThread.
Более того даже у потоков this != this->thread(), за исключением случая использования moveToThread( this ).
Записан
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #7 :
Сентябрь 02, 2011, 01:30 »
если наследник QThread испускает сигнал, то равносильно. про moveToThread( this ) всё верно.
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #8 :
Сентябрь 02, 2011, 14:04 »
Цитировать
ну, вот и правильно. как Вы выше указали, sender() в днном случае - это поток, из которого "прут данные".
если sender()->thread() == QThread::currentThread() /* равносильно qobject_cast<QThread *>(sender()) == QThread::currentThread() */, значит Qt::DirectConnection; иначе ругаемся
Равносильно, если наследник QThread испускает сигнал, и для наследника сделано moveToThread( this ).
Пусть источник и приемник сигнала живут в одном потоке. Источник не QThread. В источнике из отдельного внутреннего потока выбрасывается сигнал: Q_EMIT <источник>.someSignal(...).
В слоте при Qt::DirectConnection будет sender()->thread() != QThread::currentThread(), при других типах соединения будет равенство. Но это частный случай: источник и приемник сигнала живут в одном потоке.
Цитировать
но всё-равно этот юз-кейс какой-то странный...ни разу за свою практику мне не приходилось делать подобных проверок.
и, кстати, в случае неосмотрительности при синхронизации потоков рискуете получить по ушам) я бы советовал использовать здесь Qt::QueuedBlockedConnection /* либо пересмотреть архитектуру приложения */
В ситуациях большого объема исходных передаваемых данных, часто использую подобный дизайн в силу его простоты и производительности. После синхронной обработки объем вторичных данных может быть значительно уменьшен, и тут уже к месту Qt::QueuedConnection.
С Qt::QueuedConnection - издержки на передачу данных между потоками (копирование), или издержки на создание и поддержание общей очереди данных. Источник, который производит данные в отдельном потоке, не нагружается заботой о том, как его данные будут обрабатывать: синхронно или асинхронно.
Qt::QueuedBlockedConnection - зачастую (практически всегда, когда ждем гуй) убийственная блокировка для источников реального времени.
Записан
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #9 :
Сентябрь 03, 2011, 03:39 »
Цитата: Akon от Сентябрь 02, 2011, 14:04
Qt::QueuedBlockedConnection - зачастую (практически всегда, когда ждем гуй) убийственная блокировка для источников реального времени.
если не считать затрат на копирование данных, то более убийственная, чем Qt::DirectConnection между потоками?)
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #10 :
Сентябрь 03, 2011, 06:59 »
Простите, не понял ваш пост.
Записан
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #11 :
Сентябрь 03, 2011, 11:53 »
Цитата: Akon от Сентябрь 02, 2011, 14:04
С Qt::QueuedConnection - издержки на передачу данных между потоками (копирование), или издержки на создание и поддержание общей очереди данных. Источник, который производит данные в отдельном потоке, не нагружается заботой о том, как его данные будут обрабатывать: синхронно или асинхронно.
в силу implicit sharing природы какого-нибудь QByteArray издержки на копирование оного минимальны и можно условно принять за 0.
очередь данных уже создана и успешно поддерживается за Вас - если не производить никакого колдовства и придерживаться схемы "один обработчик не более чем для одного источника", то последовательность вызовов слота для данных будет совпадать с последовательностью эмитов сигнала с теми же данными. можете убедиться, написав несложный тест.
плюсы очевидны - поток источника данных не занимается чужой работой (а именно, обработкой данных, которая будет выполняться "клиенстким" объектом в своём потоке); и не нужно беспокоиться о межпоточной синхронизации.
Цитата: Akon от Сентябрь 02, 2011, 14:04
Qt::QueuedBlockedConnection - зачастую (практически всегда, когда ждем гуй) убийственная блокировка для источников реального времени.
> если не считать затрат на копирование данных, то более убийственная, чем Qt::DirectConnection между потоками?)
перефразирую: в чём принципиальное отличие Qt::DirectConnection от Qt::QueuedBlockedConnection в задаче, аналогичной Вашей? в чём заключается "убийственная блокировка"?
«
Последнее редактирование: Сентябрь 03, 2011, 11:55 от Константин
»
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #12 :
Сентябрь 03, 2011, 13:28 »
Цитировать
в силу implicit sharing природы какого-нибудь QByteArray издержки на копирование оного минимальны и можно условно принять за 0.
очередь данных уже создана и успешно поддерживается за Вас - если не производить никакого колдовства и придерживаться схемы "один обработчик не более чем для одного источника", то последовательность вызовов слота для данных будет совпадать с последовательностью эмитов сигнала с теми же данными. можете убедиться, написав несложный тест.
плюсы очевидны - поток источника данных не занимается чужой работой (а именно, обработкой данных, которая будет выполняться "клиенстким" объектом в своём потоке); и не нужно беспокоиться о межпоточной синхронизации.
Да, передавать данные посредством implicit sharing или посредством shared pointer очень хороший вариант. При отсутствии специфичных для моей задачи ограничений остановился бы на нем.
Опишу задачу:
Источник данных записывает сигнал со звуковухи, сама запись осуществляется внутренним потоком в специальный буфер фиксированного размера (например, это может быть невыгружаемая область памяти - дефицитный ресурс). Данные записываются кусками, при записи каждого куска выбрасывается сигнал из контекста внутреннего потока с указателем на записанный кусок.
Теперь рассмотрим клиента, который вычисляет мощность по куску сигнала (т.е. просто получает число) и обновляет прогрессбар. Оптимальным вариантом для клиента будет DirectConnection, синхронное вычисление значения и обновление проггрессбара по QueudConnection.
"убийственная блокировка" от Qt::QueuedBlockedConnection будет в том, что внутренний поток остановится, пока гуй не доберется до очереди сообщений и не вызовет слот. Это чревато банальным пропуском записываемых данных.
Записан
LisandreL
Птица говорун
Offline
Сообщений: 984
Надо улыбаться
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #13 :
Сентябрь 03, 2011, 13:46 »
Цитата: Akon от Сентябрь 03, 2011, 13:28
"убийственная блокировка" от Qt::QueuedBlockedConnection будет в том, что внутренний поток остановится, пока гуй не доберется до очереди сообщений и не вызовет слот. Это чревато банальным пропуском записываемых данных.
Qt::DirectConnection и длинный код слота также остановят ваш поток.
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #14 :
Сентябрь 03, 2011, 14:13 »
Да, но это локальный участок, и пользователь должен не допускать этого. Ведь только ему известна "тяжесть" обработки. Так все коллбэки и строятся. Если обработка достаточно "тяжела", то пользователь должен вынести ее из слота и сделать асинхронной. Qt::DirectConnection в данном случае своего рода общий знаменатель.
Записан
Страниц: [
1
]
2
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...