Events/signals/slots retaining
От: Кодёнок  
Дата: 22.07.09 05:47
Оценка: 1 (1)
 
Если говорить о системах с GC, должна ли операция добавления обработчика к событию

b.signal += a.slot


создавать сильную или слабую ссылку на a? (сильная — значит b держит a, пока не сделают -= или их не подберет GC; слабая — при сборке `a` соединение само собой разорвется).

Какие есть большие системы, реализованные обоими способами? Какие достоинства/недостатки у каждого подхода? Особенно интересно, чем каждый подход оборачивается в неидеальных командах, где не все ошибки исключаются на этапе проектирования.
Re: Events/signals/slots retaining
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.07.09 09:09
Оценка:
Здравствуйте, Кодёнок, Вы писали:

 
Кё>Если говорить о системах с GC, должна ли операция добавления обработчика к событию


Кё>
Кё>b.signal += a.slot
Кё>


Кё>создавать сильную или слабую ссылку на a? (сильная — значит b держит a, пока не сделают -= или их не подберет GC; слабая — при сборке `a` соединение само собой разорвется).


Мне кажется, что здесь общего принципа быть не может. Основной вопрос — если слот завершается или должен быть отключен, кто именно это контролирует? Если предусмотрен явный контроль этого (и он надёжен), можно использовать сильную ссылку. Если нужно явно вводить логику "не отключать до красного свистка" — то же самое. Но если контроля нет или есть настроение поставить вопрос "на самотёк" — можно использовать слабые, только не забывать их удалять (если автоудаления нет).

Достаточно чёткий случай для слабой ссылки был у меня в B2BUA. К менеджеру транзакций подписываются получатели запросов с конкретным call-id. Получатели — объекты диалогов. "Сигналы" соответствуют call-id'ам. Если диалог завершается, кто-то должен вынести его из списка подписчиков call-id. Структура этого всего — словарь с элементами — списками ссылок. Если ссылка сильная и что-то в удалении диалога происходит не так — диалог не доходит до кода выноса себя из подписки, и остаётся постоянная ссылка на него. Слабые ссылки тут пока не сделал, но планирую: что бы ни происходило при завершении диалога, он не останется висеть в памяти.

(К слову, "что бы ни происходило" тут — ключевой элемент: программа строится так, чтобы всевозможные ошибки, которые таки будут, ломали максимум тот звонок, в котором они сработали. На одновременные с этим звонки и последующие не должно быть влияния. Поэтому, накопление "мусора" тут недопустимо.)

Кё>Какие есть большие системы, реализованные обоими способами?


Какой критерий большой системы?;))
Re: Events/signals/slots retaining
От: vshabanov http://vshabanov-ru.blogspot.com
Дата: 22.07.09 10:26
Оценка:
Здравствуйте, Кодёнок, Вы писали:

 
Кё>Если говорить о системах с GC, должна ли операция добавления обработчика к событию


Кё>
Кё>b.signal += a.slot
Кё>


Кё>создавать сильную или слабую ссылку на a? (сильная — значит b держит a, пока не сделают -= или их не подберет GC; слабая — при сборке `a` соединение само собой разорвется).


Я, может быть, чего не понял. А откуда тут вообще ссылка на 'a'? В сигнал добавляется ф-ия (или что там у вас) slot, и на нее и будет ссылка. Если slot-у нужен 'a' (есть ссылка в замыкании, или чем у вас там является slot), то и на него будет ссылка через slot.
Re: Events/signals/slots retaining
От: Mr.Cat  
Дата: 22.07.09 10:52
Оценка: +1
В дотнете по дефолту используются сильные ссылки. Как следствие — можно получить "утечку" в виде объекта, подписанного на событие и никаким другим способом не используемого.
Re[2]: Events/signals/slots retaining
От: Кодёнок  
Дата: 22.07.09 12:28
Оценка:
Здравствуйте, vshabanov, Вы писали:

Кё>>b.signal += a.slot

V>Я, может быть, чего не понял. А откуда тут вообще ссылка на 'a'?

В терминах C++ a.slot эквивалентно паре &A::slot() и ссылке на `a` (чтобы было что дать в качестве this при вызове). На C# это был бы делегат, который внутри точно также сохраняет ссылку на объект и какой метод вызывать.
Re[2]: Events/signals/slots retaining
От: _FRED_ Россия
Дата: 23.07.09 06:31
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>В дотнете по дефолту используются сильные ссылки. Как следствие — можно получить "утечку" в виде объекта, подписанного на событие и никаким другим способом не используемого.


ИМХО, не так уж и сложно не наступать на эти грабли.
Help will always be given at Hogwarts to those who ask for it.
Re: Events/signals/slots retaining
От: c-smile Канада http://terrainformatica.com
Дата: 23.07.09 06:55
Оценка: +1
Здравствуйте, Кодёнок, Вы писали:

Кё>Если говорить о системах с GC, должна ли операция добавления обработчика к событию


Кё>
Кё>b.signal += a.slot
Кё>


А если 'b' это кнопка а 'a' это скажем некая функция

Ну типа

b.onClick += function() { exit(220); }


Я так понимаю что в этом случае первый же gc() сделает нашу программу невыходной (если ссылка слабая).
Re: Events/signals/slots retaining
От: _FRED_ Россия
Дата: 23.07.09 07:08
Оценка: +2
Здравствуйте, Кодёнок, Вы писали:

 
Кё>Если говорить о системах с GC, должна ли операция добавления обработчика к событию

Кё>b.signal += a.slot

Кё>создавать сильную или слабую ссылку на a? (сильная — значит b держит a, пока не сделают -= или их не подберет GC; слабая — при сборке `a` соединение само собой разорвется).

Мне кажется, что определять это должен подписчик в момент подписки. Он должен уметь (в "хороших", по моему мнению, системах) сам выбрать и решить, как должна работать создаваемая им связь.

Кё>Какие достоинства/недостатки у каждого подхода?


Тут нельзя говорить о "достоинствах-недостатках". В некоторых случаях удобнее одно, в других — другое.
Help will always be given at Hogwarts to those who ask for it.
Re: Events/signals/slots retaining
От: jazzer Россия Skype: enerjazzer
Дата: 24.07.09 01:21
Оценка: +1
Здравствуйте, Кодёнок, Вы писали:

Кё>создавать сильную или слабую ссылку на a? (сильная — значит b держит a, пока не сделают -= или их не подберет GC; слабая — при сборке `a` соединение само собой разорвется).


Кё>Какие есть большие системы, реализованные обоими способами? Какие достоинства/недостатки у каждого подхода? Особенно интересно, чем каждый подход оборачивается в неидеальных командах, где не все ошибки исключаются на этапе проектирования.


Это сильно зависит от того, что ты строишь. Как водится, одного решения на все случаи жизни нету.

Имхо, нормальные библиотеки должны предоставлять оба способа, потому что в разных случаях нужно разное.
Частенько бывает удобно создать объект только для того, чтобы отдать его в спамеру и забыть о нем, и чтоб дальше он работал самостоятельно и умер, когда умрет спамер — в этом случае сильная ссылка как раз то, что нужно.
Ближайший пример — прогресс-бар: создал, отдал и забыл.
А бывает и наоборот, естественно.

Например, в C++ в Boost.Signal можно передать как сильную ссылку на подписчика в виде shared_ptr, так и слабую, которая отвалится автоматом: http://www.boost.org/doc/libs/1_39_0/doc/html/signals2/tutorial.html#signals2.tutorial.connection-management
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.