Russian Qt Forum
Ноябрь 24, 2024, 11:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Очистка и прочее управление очередями  (Прочитано 12221 раз)
Bepec
Гость
« Ответ #15 : Декабрь 09, 2014, 10:40 »

Ну я не сомневаюсь, что можно написать потоки с имитацией поддержки очереди сигналов Веселый
Получить все сигналы возможность есть. Получить все связи возможность есть.
Остаются простые вопросы как - при дисконнекте очередь теряется или остаётся.

Но в любом случае если нельзя испортить переписать сигнал-слоты, можно создать объект под ваши нужны. При чем сигнал-слоты прям следуют вашей задаче - при отключении их от потока, будет исполнено только то, что уже было передано.

PS придумали в общем какую то неживую архитектуру, где пользователь творит херню Веселый
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #16 : Декабрь 09, 2014, 11:35 »

Наибольшая проблема даже не при дисконекте - в этом случае в очередь сигналы перестают поступать, как выяснено. Проблема, когда соединение есть, а принимающая нить не запущена или по какой-то причине стоит в ожидании. Либо просто медленнее принимает, чем передающая передает. Вот тогда очередь начинает заполняться. И если даже остановить передатчик, то приемник получает всю труху, которая была послана. Избавиться от неё возможности нет.
Записан

2^7-1 == 127, задумайтесь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Декабрь 09, 2014, 14:25 »

События (Events) я в своем приложении вообще не создаю и не использую, и не собираюсь - только обрабатываю всякие интерфейсные, которые сам Qt посылает, по необходимости.
Сигналы с QueuedConnection сами выливаются в Events.

Насчет "очистки", "объединения" очередей - это спорно/проблематично. Напр взял и очистил - а там сидел deleteLater. А потом еще найдется "исключение из правил" которое опять придется отслеживать. Как-то мутно получается.

Наибольшая проблема даже не при дисконекте - в этом случае в очередь сигналы перестают поступать, как выяснено. Проблема, когда соединение есть, а принимающая нить не запущена или по какой-то причине стоит в ожидании. Либо просто медленнее принимает, чем передающая передает. Вот тогда очередь начинает заполняться. И если даже остановить передатчик, то приемник получает всю труху, которая была послана. Избавиться от неё возможности нет.
Если используете wakeOne/All проверьте что мутекс захвачен, это коварная ошибка которая может долгое время не проявляться а тихо гадить.

По поводу Flush - да, такая нужда может возникнуть, но почему бы не решить это более простыми средствами? Напр установить нитке флаг "игнорировать события" а самому послать queued сигнал который этот флаг сбросит. При этом не нужно менять код обработчика, можно все сделать во внешнем фильтре.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #18 : Декабрь 09, 2014, 15:25 »

Проблем с wakeOne/All у меня нет (вообще эти моменты на семафорах сделаны), остановка или просто задержка нити может происходить по внешним причинам. Например, передатчик быстро генерирует управляющие команды, а приёмник посылает их на внешний прибор и считывает с него ответ. А между посылкой команды и получением ответа надо выдерживать паузу 200 мсек. В результате приемник команд обрабатывает команды только каждые 0.2 сек. А передатчик команд может молотить их по чем зря. А потом прибор вдруг не ответил, выдал ошибку - приёмник команды должен выдать сообщение и стать в ожидании действия оператора. И после ответа оператора все команды, которые были посланы передатчиком, уже не нужны, их надо выкинуть - а они сейчас сидят в очереди. Это одна из возможных ситуаций, для которых надо специально предусматривать дополнительные синхронизации, сигналы управления, какие-то ухищрения и т.д. Хотя, если бы была просто приостановка передатчика по заполнению очереди некоей выделенной длины - это можно было бы использовать одинаково со всеми внешними приборами, которые имеют задержку ответа, и которые не имеют. Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике.

Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал.
Записан

2^7-1 == 127, задумайтесь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Декабрь 09, 2014, 16:19 »

Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал.
Вы бы не пихали. А автор одного из Ваших плагинов - запихнул. Это я просто для примера, к тому что возможность "очистить очередь" вряд ли принесет много счастья, скорее наоборот, добавит головняка. Ведь придется разбираться что можно мочить а что нельзя - это как минимум несладко.

Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике.
Не вижу повода для эмоций/негодования. По-моему такое решение грамотнее и надежнее "очистки событий". Да, приемник оповещен и знает что до какого-то события надо игнорировать какие-то действия, что в этом плохого?

Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #20 : Декабрь 09, 2014, 16:54 »

Насчет deleteLater - ИМХО это уже выдумка. Если такой объект послать в очередь обмена между нитями, то вообще не вполне понятно, когда он будет удален даже без очистки очереди. Может грохнуться в момент получения слотом в параллельной нити. Я бы такие объекты в очередь не пихал.
Вы бы не пихали. А автор одного из Ваших плагинов - запихнул. Это я просто для примера, к тому что возможность "очистить очередь" вряд ли принесет много счастья, скорее наоборот, добавит головняка. Ведь придется разбираться что можно мочить а что нельзя - это как минимум несладко.

Ну а без очистки очереди просто @$#%&@Q#... Пока пришлось в одном случае вые...ться и сделать специальный цикл выборки очереди в приемнике.
Не вижу повода для эмоций/негодования. По-моему такое решение грамотнее и надежнее "очистки событий". Да, приемник оповещен и знает что до какого-то события надо игнорировать какие-то действия, что в этом плохого?

Первый случай решается легко строкой в документации - "нельзя посылать в очередь объекты с deleteLater, кто послал, тот сам дурак". А вот второй случай означает, что авторам плагинов надо будет знать, в каких случаях писать собственный код для очистки очереди, в каких нет. Либо мне надо в родительском классе плагинов как-то предусматривать возможность выборки мусора из очереди (она может не в каждом случае потребоваться), чтобы самим авторам этого не пришлось делать, но тогда надо еще и в документации описать использование всего этого. То есть, отсутствие возможности просто очистить очередь одним вызовом, а вместо этого необходимость множества не совсем тривиальных действий, и порождает негодование. Тем более обоснованное, что внутри Qt это наверняка есть.
Записан

2^7-1 == 127, задумайтесь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #21 : Декабрь 09, 2014, 17:35 »

Первый случай решается легко строкой в документации - "нельзя посылать в очередь объекты с deleteLater, кто послал, тот сам дурак". А вот второй случай означает, что авторам плагинов надо будет знать, в каких случаях писать собственный код для очистки очереди, в каких нет. Либо мне надо в родительском классе плагинов как-то предусматривать возможность выборки мусора из очереди (она может не в каждом случае потребоваться), чтобы самим авторам этого не пришлось делать, но тогда надо еще и в документации описать использование всего этого. То есть, отсутствие возможности просто очистить очередь одним вызовом, а вместо этого необходимость множества не совсем тривиальных действий, и порождает негодование. Тем более обоснованное, что внутри Qt это наверняка есть.
А не лучше ли не связываться ни с какой "очисткой" а решить это запросом статуса на приемнике и/или передатчике? Псевдокод как это решается в плагинах моей системы
Код
C++ (Qt)
SInt32 PluginCommand( UInt32 theCommand, .. )
{
switch (theCommand) {
 case commandCreateGeometry:
   for (size_t i = 0; i < N; ++i) {
     if (GetObjectStatus(dstObject) != noErr)
       return code_Aborted;
     AddVertex(dstObject, i, ...);
  }
  return noErr;
...
}
Т.е. перед посылкой запросить статус, а не так, "на деревню дедушке". Вообще всегда есть коды возврата и текущее состояние плагина - через них и надо действовать, т.е. цивильно, вместо цыганщины с "очисткой очереди".
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #22 : Декабрь 10, 2014, 01:07 »

Не поможет. Потому как когда в предыдущем примере приемник встанет по ошибке прибора, будет поздно пить боржоми - в очереди уже будет дофига ненужного. А если жестко синхронизировать передатчик и приёмник (напоминаю, что они в разных нитях), то они уже не независмы. Но по задаче подразумевается, что передатчик ничего не знает о приемнике, а приемник о передатчике. Приемники могут быть разные и передатчики разные. Даже обмен идет в QVariant обертках. И даже соединения могут меняться пользователем динамически.
« Последнее редактирование: Декабрь 10, 2014, 01:09 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.075 секунд. Запросов: 22.