![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Peter |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 28.7.2003 Где: Ставрополь Репутация: -1 Всего: 1 |
Конкретно дело обстоит так. Многооконное приложение; каждое дочернее окно - объект класса <КлассДокумента>. Когда дочернее окно открыто, в объекте этого класса может выполняться некоторая операция (функция F вызывается по таймеру). В функции F используется переменная x - член класса <КлассДокумента>, имеющий тип "указатель на структуру S". В конструкторе <КлассДокумента>
в деструкторе
Рассмотрим следующую ситуацию (которая наблюдалась в работе программы): в момент выполнения функции F пользователь закрывает окно. В деструкторе уничтожается объект, на который указывает x, и в то же самое время x используется в F. Если ничего не предпринимать, то программа вылетает. Может ли что-нибудь испортиться, если я заключу тело F в
?????????????? Не повредится ли, например, стэк? -------------------- всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23). |
||||||
|
|||||||
| Fedor |
|
|||
![]() Днепрянин ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2090 Регистрация: 8.2.2003 Где: Великий Репутация: нет Всего: 32 |
может, я туплю, но разве такое может быть? события разве не поочереди выполняются? т.е. сначала до конца до работает функция, а потом только вызовется деструктор? Буду рад, если поправите меня. -------------------- Мы - Днепряне. Мы всех сильней. |
|||
|
||||
| Mayk |
|
||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
А может стоит воспользваться чем-нибудь типа shared_ptr, или еще каким имеющимся классом для
подсчета ссылок? В крайнем случае накатать самому.
Если приложение многопоточное, и деструктор вызовется не из того потока, в котором выполняется F, то может прийти Большой Ой. Добавлено @ 23:12
А что нам это даст?
завершается нормально -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||
|
|||||||
| chipset |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Курим MSDN на тему синхронизации потоков или используем метод подсчета ссылок как правильно подметил Mayk
--------------------
|
|||
|
||||
| Peter |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 28.7.2003 Где: Ставрополь Репутация: -1 Всего: 1 |
Первое нам даст то, что при выполнении F программа не вылетит. Второе не подходит (наверно, имелось в виду
Синхронизация потоков, конечно, это хорошо, но слишком долго, и в ней нет необходимости, поскольку результат работы функции F пользователя уже не интересует. А поставить try-catch - это дело нескольких секунд. Вопрос лишь в том, не может ли быть от этого побочных эффектов? -------------------- всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23). |
||||||||
|
|||||||||
| Mayk |
|
||||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Ага
Да ну? Вы СЛИШКОМ высокого мнения об исключениях. В мной указаном примере произошла запись в уже удаленный s. И исключения не возникло(откуда? кто будет кидать исключение? система? а как она узнает что память освобождена?). Точно так же оно не возникнет если в Вашей программе удалить объект из другого потока: Исключения не связаны с синхронизацией потоков. Исключения не возникают, когда происходит запись не туда куда надо. Исключения не вознакают, когда происходит чтения из разрушенного/(что еще хуже) полуразрушенного объекта. Чтобы поймать исключения, его нужно кинуть Исключение не может быть поймано, если оно не брошено. Кстати. В качестве альтернативы. Грубешая и не правильная синхронизация может выглядеть так:
И наблюдаем за крахом, в тот момент, когда один поток начнет выполнять F, прервется до x->doNotDeleteMe = true;, передаст управление другому потоку, который благополучно разрушит x. ОЙ.
В ней (или в альтернативе из подсчёта ссылок => позднего удаления) есть необходимость. Иначе программа умрёт. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||||
|
|||||||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Синхронизация и подсчет ссылок - это не альтернативы, а Необходимые Вещи (причем обе сразу). Впрочем, вместо подсчета ссылок можно придумать какой-нибудь другой механизм управления владением и временем жизни. Но подсчет ссылок - наиболее простой и естественный в данном случае, ИМХО.
Но если есть разные потоки, работающие с одними и теми же данными, в синхронизации всегда есть необходимость! В данном случае это касается возможной реализации shared_ptr - придется позаботиться о том, чтобы все его методы были потокобезопасны (скажем, инкремент-декремент числа ссылок должен быть атомарным, и т.д.). Иначе твоя программа будет работать или валиться в зависимости от погоды на Галапагосских островах. -------------------- ... |
|||
|
||||
| Peter |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 28.7.2003 Где: Ставрополь Репутация: -1 Всего: 1 |
Специально для проверки ставил
и сообщение в message-box было благополучно показано, а программа продолжала работать.
Ищу дешевый способ починить программу. Если не найду, придется делать синхронизацию потоков. Это сообщение отредактировал(а) Peter - 9.1.2006, 22:56 -------------------- всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23). |
||||||
|
|||||||
| threef |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 27.10.2005 Где: Запорожье Репутация: 9 Всего: 10 |
Стек не повредится, x указывает на кучу.
Как у тебя происходит управление функцией F , вернее, таймером ? Если таймер привязан к существовании этого дочернего окна, то просто убей его в OnDestroy этого окна. Если у тебя функция по таймеру очень медленная, ( в процессе ее однократного выполнения пользователь может открыть и закрыть окно) , то все равно в однопотоковом приложении этого просто не произойдет
Примечание: при использовании многопоточности действительно могут возникнуть всякие ОЙ, этим методом пользоваться нельзя. |
|||
|
||||
| Peter |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 28.7.2003 Где: Ставрополь Репутация: -1 Всего: 1 |
Приложение многопоточное.
-------------------- всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23). |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |