Название: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 11:13 Известно, что у Qt по необъяснимым причинам нет никакого управления очередями при соответствующих соединениях сигнал/слот. Очередь нельзя принудительно очистить, нельзя управлять её длиной, нельзя её "сливать" (игнорировать выход, если она никуда не подключена). Я искал объяснения, но ничего вменяемого не нашёл.
Есть желающие обсудить этот вопрос? Мне лично потребовалась необходимость очистки очереди и управления её длиной. Может стоит feature request написать? Или этот вопрос уже ранее поднимался (я с версии Qt 3.3 такого не помню, может прозевал)? Название: Re: Очистка и прочее управление очередями Отправлено: Пантер от Декабрь 08, 2014, 11:16 Для чего тебе понадобилась такая возможность? Скорее всего, можно проблему решить по-другому.
Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 11:28 Для чего тебе понадобилась такая возможность? Скорее всего, можно проблему решить по-другому. Для того, что в задаче нити общаются через очереди, а соединения между нитями могут динамически меняться, вплоть до отключения. Надо иметь возможность очистки оторванной очереди и ограничения длины, чтобы нить при достижении очередью определенной длины останавливалась (как в случае QBlockingQueued). По-другому нормально - никак. А очереди в Qt - не объекты, во всяком случае, их структура снаружи не видна, их нельзя унаследовать и написать поверх них свой функционал. Название: Re: Очистка и прочее управление очередями Отправлено: Old от Декабрь 08, 2014, 11:46 Пришло время использовать свои очереди.
Название: Re: Очистка и прочее управление очередями Отправлено: Пантер от Декабрь 08, 2014, 11:56 Да, свои очереди делай.
Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 08, 2014, 12:38 Известно, что у Qt по необъяснимым причинам нет никакого управления очередями при соответствующих соединениях сигнал/слот. Очередь нельзя принудительно очистить, нельзя управлять её длиной, нельзя её "сливать" (игнорировать выход, если она никуда не подключена). Я искал объяснения, но ничего вменяемого не нашёл. Это не совсем так. Есть метод compressEvent (правда не документированный)Есть желающие обсудить этот вопрос? Мне лично потребовалась необходимость очистки очереди и управления её длиной. Может стоит feature request написать? Или этот вопрос уже ранее поднимался (я с версии Qt 3.3 такого не помню, может прозевал)? Написание feature request - это как бы "жест доброй воли" или благотворительность. Возможно через годик Вы с удовольствием заметите "ага, молодцы, сделали!", но может и нет, им ведь тоже надо "поднимать проект". Во всяком случае надеяться решить свои проблемы с помощью feature request не стоит.Я бы сначала поизучал compressEvent, сделал бы нужные операции с очередью как "тоже событие". Это просто предложение, оценивать типа "а вот это уже чепуха" не надо :) Может и чепуха, может и нет. Название: Re: Очистка и прочее управление очередями Отправлено: Bepec от Декабрь 08, 2014, 13:09 Механизм сигнал слот в Qt отлажен и подходит под 99% нужд, не заставляя даже задумываться о том, как оно работает. А у вас задача как раз в 1% попадает, в котором вам надо изменить механизм.
И если допустим они возьмутся за реализацию управления всем этим, то придётся весь механизм переписывать. Сейчас он прост и не вызывает затруднений именно тем, что хрен кто в него влезет :D PS моё мнение - проще вам свою очередь написать. Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 18:38 Свою очередь - однозначно не проще. Там всё по затылок в сигналах-слотах, а это означало бы написать их и большую часть приложения.
Причем 100% все нужные механизмы наверняка в очередях есть, иначе они бы вообще не работали. Просто наружу не вытащено. Не вижу пока, как compressEvent может помочь хотя бы очистить очередь. Название: Re: Очистка и прочее управление очередями Отправлено: Bepec от Декабрь 08, 2014, 18:50 Всё там есть, и очистка, и получение количества сигналов, и многое другое. Вот ток оно внутри. Коммерческую лицензию и флаг в руки.
Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 08, 2014, 19:09 Не вижу пока, как compressEvent может помочь хотя бы очистить очередь. Да хотя бы такКод Только вряд ли это нужно/разумно делать Свою очередь - однозначно не проще. Там всё по затылок в сигналах-слотах, а это означало бы написать их и большую часть приложения. Категоричные суждения обычно поверхностны. Своя очередь практически неизбежна. Обычно она имеет высший приоритет (т.е. сначала выбираются все события из "своей" очереди, напр в eventFilter). Смешивать очереди не резон. Засылать события в свою очередь можно хоть напрямую, хоть с подскоком из того же compressEventВсё там есть, и очистка, и получение количества сигналов, и многое другое. Вот ток оно внутри. Коммерческую лицензию и флаг в руки. Ну вот после таких ответов нервный ТС блокирует тему :) Цитировать Суп на пароходе - прямо из Парижв! Открываешь кастрюльку - а там паааар.. :)Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 19:24 Увы, свою очередь делать не с руки, придётся весь механизм сигнал-слотов дублировать, потому что на него эта часть приложения полностью опирается. Общение между параллельными нитями сделано на сигналах и слотах, нити в плагинах, связывание сигналов и слотов автоматическое при загрузке плагинов, всё спроектировано, и в основном отлажено. А перепахивать приложение сейчас уже нет времени. На коммерческую лицензию сейчас денег никто не даст. А значит самый простой вариант - feature request, авось исполнится.
Название: Re: Очистка и прочее управление очередями Отправлено: Old от Декабрь 08, 2014, 19:28 А значит самый простой вариант - feature request, авось исполнится. Еще можно свечу в церкви поставить, может помочь. ;)Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 08, 2014, 20:07 Увы, свою очередь делать не с руки, придётся весь механизм сигнал-слотов дублировать, потому что .. Чего это дублировать? Очереди "рабочих ниток" - что в них может быть кроме сигналов посланных из др ниток? По-моему аж ничего. Значит с ними можно напрямую. С главной ниткой так вряд ли прокатит, ну так если Вы собрались сливать/удалять - значит знаете что, т.е. интересующие события/получатели известны. Что мешает их выделить их отдельно? Выполнять их первыми - не проблемаНазвание: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 20:22 Очереди "рабочих ниток" - что в них может быть кроме сигналов посланных из др ниток? По-моему аж ничего. Ну например, у меня с нитками через стандартные сигнал-слоты весь интерфейс общается. Которого не мало. Да и вообще вся главная нить. И пользователь может через этот интерфейс динамически подключать и отключать сигналы, даже во время выполнения нитей. Сейчас это всё без проблем работает на базовых сигналах. На своих - придется написать их фактически эквивалент, и еще не вполне понятно, как он должен взаимодействовать с базовыми сигналами. Именно с сигналами, это у меня основной механизм обмена. Всё приложение прошито соединениями, как мозг млекопитающего синапсами. События (Events) я в своем приложении вообще не создаю и не использую, и не собираюсь - только обрабатываю всякие интерфейсные, которые сам Qt посылает, по необходимости. Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 08, 2014, 20:27 Не, писать свои очереди я пока не буду. А вот запрос на фичу уже написал. ;D
Кстати, вспомнил - где-то еще в версии Qt 2.х, когда я с ним только знакомился, в его тусовке горячо обсуждался вопрос управления очередями. Противники говорили, что это нарушает принцип объектности и идеологию Qt, якобы дает возможность вмешательства в святыни. Сторонники говорили, что не будет нарушений, если очередью сможет управлять только тот, кто в неё посылает, этого будет достаточно. AFAIR тогда сказали, что это обсуждение будет продолжено в версии 3.х. Там, судя по всему, про это всё забыли. Но тогда еще не так горячо требовалась поддержка распараллеливания. Сейчас требуется. У меня в некоторые моменты времени работают 8 нитей одновременно, и это еще только середина разработки... Название: Re: Очистка и прочее управление очередями Отправлено: Bepec от Декабрь 09, 2014, 10:40 Ну я не сомневаюсь, что можно написать потоки с имитацией поддержки очереди сигналов :D
Получить все сигналы возможность есть. Получить все связи возможность есть. Остаются простые вопросы как - при дисконнекте очередь теряется или остаётся. Но в любом случае если нельзя PS придумали в общем какую то неживую архитектуру, где пользователь творит херню :D Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 09, 2014, 11:35 Наибольшая проблема даже не при дисконекте - в этом случае в очередь сигналы перестают поступать, как выяснено. Проблема, когда соединение есть, а принимающая нить не запущена или по какой-то причине стоит в ожидании. Либо просто медленнее принимает, чем передающая передает. Вот тогда очередь начинает заполняться. И если даже остановить передатчик, то приемник получает всю труху, которая была послана. Избавиться от неё возможности нет.
Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 09, 2014, 14:25 События (Events) я в своем приложении вообще не создаю и не использую, и не собираюсь - только обрабатываю всякие интерфейсные, которые сам Qt посылает, по необходимости. Сигналы с QueuedConnection сами выливаются в Events.Насчет "очистки", "объединения" очередей - это спорно/проблематично. Напр взял и очистил - а там сидел deleteLater. А потом еще найдется "исключение из правил" которое опять придется отслеживать. Как-то мутно получается. Наибольшая проблема даже не при дисконекте - в этом случае в очередь сигналы перестают поступать, как выяснено. Проблема, когда соединение есть, а принимающая нить не запущена или по какой-то причине стоит в ожидании. Либо просто медленнее принимает, чем передающая передает. Вот тогда очередь начинает заполняться. И если даже остановить передатчик, то приемник получает всю труху, которая была послана. Избавиться от неё возможности нет. Если используете wakeOne/All проверьте что мутекс захвачен, это коварная ошибка которая может долгое время не проявляться а тихо гадить.По поводу Flush - да, такая нужда может возникнуть, но почему бы не решить это более простыми средствами? Напр установить нитке флаг "игнорировать события" а самому послать queued сигнал который этот флаг сбросит. При этом не нужно менять код обработчика, можно все сделать во внешнем фильтре. Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 09, 2014, 15:25 Проблем с wakeOne/All у меня нет (вообще эти моменты на семафорах сделаны), остановка или просто задержка нити может происходить по внешним причинам. Например, передатчик быстро генерирует управляющие команды, а приёмник посылает их на внешний прибор и считывает с него ответ. А между посылкой команды и получением ответа надо выдерживать паузу 200 мсек. В результате приемник команд обрабатывает команды только каждые 0.2 сек. А передатчик команд может молотить их по чем зря. А потом прибор вдруг не ответил, выдал ошибку - приёмник команды должен выдать сообщение и стать в ожидании действия оператора. И после ответа оператора все команды, которые были посланы передатчиком, уже не нужны, их надо выкинуть - а они сейчас сидят в очереди. Это одна из возможных ситуаций, для которых надо специально предусматривать дополнительные синхронизации, сигналы управления, какие-то ухищрения и т.д. Хотя, если бы была просто приостановка передатчика по заполнению очереди некоей выделенной длины - это можно было бы использовать одинаково со всеми внешними приборами, которые имеют задержку ответа, и которые не имеют. Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике.
Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал. Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 09, 2014, 16:19 Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал. Вы бы не пихали. А автор одного из Ваших плагинов - запихнул. Это я просто для примера, к тому что возможность "очистить очередь" вряд ли принесет много счастья, скорее наоборот, добавит головняка. Ведь придется разбираться что можно мочить а что нельзя - это как минимум несладко.Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике. Не вижу повода для эмоций/негодования. По-моему такое решение грамотнее и надежнее "очистки событий". Да, приемник оповещен и знает что до какого-то события надо игнорировать какие-то действия, что в этом плохого?Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 09, 2014, 16:54 Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал. Вы бы не пихали. А автор одного из Ваших плагинов - запихнул. Это я просто для примера, к тому что возможность "очистить очередь" вряд ли принесет много счастья, скорее наоборот, добавит головняка. Ведь придется разбираться что можно мочить а что нельзя - это как минимум несладко.Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике. Не вижу повода для эмоций/негодования. По-моему такое решение грамотнее и надежнее "очистки событий". Да, приемник оповещен и знает что до какого-то события надо игнорировать какие-то действия, что в этом плохого?Первый случай решается легко строкой в документации - "нельзя посылать в очередь объекты с deleteLater, кто послал, тот сам дурак". А вот второй случай означает, что авторам плагинов надо будет знать, в каких случаях писать собственный код для очистки очереди, в каких нет. Либо мне надо в родительском классе плагинов как-то предусматривать возможность выборки мусора из очереди (она может не в каждом случае потребоваться), чтобы самим авторам этого не пришлось делать, но тогда надо еще и в документации описать использование всего этого. То есть, отсутствие возможности просто очистить очередь одним вызовом, а вместо этого необходимость множества не совсем тривиальных действий, и порождает негодование. Тем более обоснованное, что внутри Qt это наверняка есть. Название: Re: Очистка и прочее управление очередями Отправлено: Igors от Декабрь 09, 2014, 17:35 Первый случай решается легко строкой в документации - "нельзя посылать в очередь объекты с deleteLater, кто послал, тот сам дурак". А вот второй случай означает, что авторам плагинов надо будет знать, в каких случаях писать собственный код для очистки очереди, в каких нет. Либо мне надо в родительском классе плагинов как-то предусматривать возможность выборки мусора из очереди (она может не в каждом случае потребоваться), чтобы самим авторам этого не пришлось делать, но тогда надо еще и в документации описать использование всего этого. То есть, отсутствие возможности просто очистить очередь одним вызовом, а вместо этого необходимость множества не совсем тривиальных действий, и порождает негодование. Тем более обоснованное, что внутри Qt это наверняка есть. А не лучше ли не связываться ни с какой "очисткой" а решить это запросом статуса на приемнике и/или передатчике? Псевдокод как это решается в плагинах моей системыКод Т.е. перед посылкой запросить статус, а не так, "на деревню дедушке". Вообще всегда есть коды возврата и текущее состояние плагина - через них и надо действовать, т.е. цивильно, вместо цыганщины с "очисткой очереди". Название: Re: Очистка и прочее управление очередями Отправлено: Гурман от Декабрь 10, 2014, 01:07 Не поможет. Потому как когда в предыдущем примере приемник встанет по ошибке прибора, будет поздно пить боржоми - в очереди уже будет дофига ненужного. А если жестко синхронизировать передатчик и приёмник (напоминаю, что они в разных нитях), то они уже не независмы. Но по задаче подразумевается, что передатчик ничего не знает о приемнике, а приемник о передатчике. Приемники могут быть разные и передатчики разные. Даже обмен идет в QVariant обертках. И даже соединения могут меняться пользователем динамически.
|