Показать полную графическую версию : multithread & exception-safe
Здравствуйте DillerInc. Похоже форум превращается в диалог. Вы пишете, что в коде, который я представил, поток являющийся точкой входа в программу, ничего не делает, а только ждёт запланированного исключения. Не согласен с этим. Вместо Sleep можно поставить другие операторы и вообще опрашивать состояние переменной _exc_message в цикле попутно выполняя полезную работу. Правда у имеющейся программы есть недостаток: о создавшемся исключении основной поток узнаёт только через секунду. Кстати DillerInc, напишите что нужно сделать, чтобы вызвавший поток мгновенно оповещался о наступлении исключения в другом потоке. В статье Гордона это упоминалось. О недостатках такого способа вы как раз написали. Удачи.
DillerInc
10-03-2008, 12:17
podsyp, касательно многопоточных приложений в статье Гордона упор делается на корректное завершение потоков,которые непричастны к возникновению ошибки.Речь идёт о завершении процесса.
* Для этого первым делом в главном потоке устанавливается свой финальный обработчик с помощью функции SetUnhandledExceptionFilter.
* Когда система будет намерена завершить процесс из-за необработанного исключения,она вызовет этот наш финальный обработчик.
* Далее используется глобальная переменная,которая в финальном обработчике выставляется,например,в значение TRUE.Потоки приложения должны в цикле полезной работы проверять значение этой переменной.Если значение переменной равно TRUE, то они должны освободить ресурсы и завершится.
* Завершение потока есть событие.Поэтому в финальном обработчике после установки переменной необходимо вызвать функцию WaitForMultipleObjects, чтобы ожидать завершения всех указанных потоков.
* Затем выход из финального обработчика,и процесс убивается системой.
Вот так вот.
Я ждал от вас DillerInc этого ответа. Но по моему прелесть многопоточности в том, что в одном потоке вызывается и перехватывается исключение , а другие работают себе как ни в чём ни бывало. А так представьте - один поток у вас музыку играет, другой анимацию делает, а третий вычисления производит. И вдруг в ходе вычислений происходит деление на ноль. Так что - все остальные потоки должны при этом завершится, пусть даже с корректным освобождением ресурсов? Так было в старые времена, когда никто про Windows и слыхом не слыхивал, работает себе программа и случается ошибка. И всё встаёт. В вашем описанном случае тоже не всё здорово? Возможно это и необходимо для программ, в которых не предусмотренно использования try - catch в каждом потоке. Но вообще как мне кажется включать для каждого потока свой try - catch хорошая практика. Пока она не "узаконена" производителями компиляторов, но ведь например раньше и такого понятия как свойство не было. Зато призывов не обращатся к внутренним переменным класса напрямую - в любой книжке по программированию было навалом. Функция WaitForMultipleObjects судя по названию как раз и занимается тем, что сидит и ждёт пока что нибудь страшное не случится. Видимо её я как раз и имел в виду когда спрашивал о мгновенном оповещении. Только в шарпе у неё оболочка AutoResetEvent. Ожидание производится функцией WaitOne(), а событие порождается функцией Set(). Создаёте отдельный поток для ожидания события который всего и делает что асинхронно ждёт наступления события. А вы меня ещё укоряли как это так моя программа ожидает запланированного исключения. Альтернативный вариант - это использование событий, как в том варианте что я выкладывал. Преимущество событий перед AutoResetEvent в том что они помимо сигнализации о себе могут передать информацию. И при этом не нужно создавать глобальных переменных. Для маленьких программ создание глобальных переменных может быть не такое уж зло, но для больших - крайне не желательно. Программа становится как бы завязанной в один узел, её трудно разделить на независимые части, поскольку для всех переменные одни. Удачи.
DillerInc
10-03-2008, 19:53
В общем,мне надоело уже тут биться об стену.Если вы такой умный,то разбирайтесь сами со своими "до-диезами".
DillerInc, 2 поста назад - свежий взгляд (для моих мозгов), это тема, чёто не подумал раньше как-то. Ведь действиельно, если поток ещё работоспособный, он должен закончиться естественным образом (то бишь по проверке isApplicationTerminated).
podsyp, я бы всё-таки почитал литературу от создателей С++ (только не через призму С#), всё задумывалось совсем не так, а потом ребята из sun всё извратили, хотя получилось неплохо.
Когда программа завершается (любым способом), операционка может почистить за ней мусор и перезапустить её при необходимости, так что ничего не встанет. Слишком самоуверенные программы (которые в случае необработанного искобчения продолжают работать) несут большой риск...
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.