Russian Qt Forum
Ноябрь 23, 2024, 19:33
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Общие вопросы
>
Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
Страниц:
1
[
2
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection? (Прочитано 10561 раз)
ритт
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #15 :
Сентябрь 03, 2011, 15:42 »
Вы, вроде бы, механизм понимаете правильно, но жонглиреуете фактами, как заправский циркач, игнорируя плюсы и выдавая минусы за плюсы другого характера
Qt::DirectConnection или Qt::QueuedBlockedConnection - в Вашем случае разницы никакой (я намеренно опускаю наличие межпоточной блокировки во втором случае). никакого пропуска данных там нет и не будет. упрощая описанную в третьем посте схему, приходим к тому, что слот Вам вовсе и не нужен - достаточно приватного метода, исполняемого в контексте источника данных. но т.к. у Вас некий "клиентский" обект, то допускаю, что какие-то его члены должны быть потоко-безопасными (а иначе я вообще не вижу смысла в этом объекте). подключая слот через Qt::DirectConnection, Вы усложняете себе жизнь необходимостью скрупулёзно следить за lock-free потокобезопасностью, но получаете возможность использовать некий дефицитный ресурс в качестве буфера данных. независимо от того, "тяжёлая" операция производится в слоте или нет, источник данных (поток) занимается не своей задачей, данные в это время накапливаются в некотором ином буфере, возникает потенциальная задержка, а возможности как-либо контролировать её нет (разве что, "пробрасывать" часть данных - чего Вы, кажется, пытаетесь избежать).
давайте рассмотрим простейшую альтернативу: источник данных имеет пишет в не-такой-дефицитный implicitly shared буфер и выбрасывает queued сигнал со ссылкой на него { QMetaObject::invokeMethod(this, "dataChunkReceived", Qt::QueuedConnection, Q_ARG(QByteArray, &ba)); }, абсолютно не беспокоясь о том, кто и с какими параметрами подключён к сигналу dataChunkReceived(const QByteArray &), после чего сразу же возвращается к своей прямой обязанности - ждать данные и складывать их в буфер. имея пару-тройку буферов в распоряжении, вероятность memory reallocation любого из буферов стремится к нулю. слот, подключённый к вышеобозначенному сигналу, уже в другом контексте выполняет над данными произвольные операции, швыряется произвольными сигналами либо же попросту спит минуту, но следующий кусок данных он таки получит. проблема только в том, что если объект действительно спит минуту, в очереди событий будут накапливаться всё новые и новые данные, что эффективно решает "проброской" данных, которые уже неактуальны. но раз уж у Вас достаточно навыков и времени на поддержание lock free синхронизации между несколькими объектами, то задача обработки данных "в срок" и/или "проброски" неактуальных данных для Вас будет проще пареной репы;) если же "проброска" данных исключена, несложно добавить в источник данных механизм обнаружения неэффективного использования буферов и усыпления потока - будет 1-в-1 то же самое, что у Вас сейчас происходит при вызове слота, подключённого с Qt::DirectConnection.
у нас подобная схема успешно справляется в десятками видео-потоков средней плотности. включая рендеринг. не побоюсь предположить, что в контексте Вашей задачи это были бы сотни потоков аудио стандартного битрейта (если не упрётся в ограничения звуковой карты).
но я не навязываюсь с данной схемой - просто рассмотрел возможные альтернативы
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #16 :
Сентябрь 03, 2011, 20:21 »
Ну почему "жонглирует", case вполне естественный, напр клиенту нужно быстро проверить "а нужны ли мне пришедшие данные" (может и нет). Добраться до нитки клиента может быть очень непросто, поэтому выполнение в нитке вызывающего. Делать это на стороне сервера - открывать подробности реализации клиента, не гуд.
Как определить - ну а если незатейливо в run клиента запомнить его currentThreadId и проверять на неравенство текущему?
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #17 :
Сентябрь 03, 2011, 23:44 »
Цитата: Константин от Сентябрь 03, 2011, 15:42
но я не навязываюсь с данной схемой - просто рассмотрел возможные альтернативы
Всегда рад различного рода альтернативам
Спасибо.
Цитировать
давайте рассмотрим простейшую альтернативу: источник данных имеет пишет в не-такой-дефицитный implicitly shared буфер и выбрасывает queued сигнал со ссылкой на него { QMetaObject::invokeMethod(this, "dataChunkReceived", Qt::QueuedConnection, Q_ARG(QByteArray, &ba)); }, абсолютно не беспокоясь о том, кто и с какими параметрами подключён к сигналу dataChunkReceived(const QByteArray &), после чего сразу же возвращается к своей прямой обязанности - ждать данные и складывать их в буфер. имея пару-тройку буферов в распоряжении, вероятность memory reallocation любого из буферов стремится к нулю
Спору нет - такая схема очень элегантна, когда источнику данных позволительно выделить дополнительную память, и частота такого выделения приемлемо низка. Схему можно еще немного оптимизировать, если под чанки использовать implicitly shared но без copy on write (т.е. просто allocate on write).
Пусть в приведенном мною примере с вычислением мощности чанка происходит переполнение буфера - в вашей схеме будет выделена память под целый чанк, в моей, этого не будет, поскольку клиент по чанку получает всего лишь число (int).
Цитировать
Qt::DirectConnection или Qt::QueuedBlockedConnection - в Вашем случае разницы никакой (я намеренно опускаю наличие межпоточной блокировки во втором случае). никакого пропуска данных там нет и не будет.
Если блокировка будет на время, не меньшее времени заполнения остатка буфера, то будет потеря данных на уровне взаимодействия источника данных со звуковухой (запрос на очередной чанк не будет выдан вовремя). На участке источник данных - клиент (что, по всей видимости, вы имели ввиду) потерь данных нет.
Цитировать
Как определить - ну а если незатейливо в run клиента запомнить его currentThreadId и проверять на неравенство текущему?
Да, и так вот незатейливо
неравенство будет означать, что слот вызван из другой нитки, т.к. с QueuedConnection он может быть вызван только из своей!
Записан
LisandreL
Птица говорун
Offline
Сообщений: 984
Надо улыбаться
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #18 :
Сентябрь 04, 2011, 03:25 »
Цитата: Akon от Сентябрь 03, 2011, 14:13
Да, но это локальный участок, и пользователь должен не допускать этого. Ведь только ему известна "тяжесть" обработки. Так все коллбэки и строятся. Если обработка достаточно "тяжела", то пользователь должен вынести ее из слота и сделать асинхронной. Qt::DirectConnection в данном случае своего рода общий знаменатель.
Странно расчитывать, на то, что с тяжестью обработки пользователь сам разберётся, а с нужным типом коннекта - нет.
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #19 :
Сентябрь 04, 2011, 08:20 »
Пользователь и не разбирается с типом коннекта - ему предлагается только DirectConnect. У себя в слоте, если необходимо, далее делается QueuedConnect.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #20 :
Сентябрь 04, 2011, 09:29 »
Пусть даже простейший вариант, без всяких оптимизаций/заморочек: клиент просто принимает все запросы. Почему сервер должен знать как толкнуть клиента. с каких мутексов его снять и.т.п? Более чисто смотрится "сервер уведомляет", а уж клиент разбирается как запуститься. И уведомление должно выполняться в нитке сервера (нитка клиента остановлена)
Цитата: Akon от Сентябрь 03, 2011, 23:44
Да, и так вот незатейливо
неравенство будет означать, что слот вызван из другой нитки, т.к. с QueuedConnection он может быть вызван только из своей!
Ну да, а разве Вам не это надо?
Записан
Akon
Гость
Re: Как проверить, что для данной пары сигнал/слот установлено Qt::DirectConnection?
«
Ответ #21 :
Сентябрь 04, 2011, 10:15 »
Цитата: Igors от Сентябрь 04, 2011, 09:29
Ну да, а разве Вам не это надо?
Да, применительно к описанной мною задаче это должно работать, спасибо!
Изначальный вопрос ("Как проверить, что для данной пары сигнал/слот установлено 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 сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...