metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2008-06-25 02:35 pm

Почему у людей в головах такой страшный бред?

отсюда

Q. У меня неправильно работает многопоточное приложение, иногда не снимается блокировка с ресурса.
A1, нормальный :Используйте правильный паттерн блокировки с обработкой исключений
A2, от красноглазых психов: Используйте POSIX, потому что микрософтовские поделки глючны и содержат в себе только маркетинговые ходы.

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

[identity profile] mr-st.livejournal.com 2008-06-25 11:52 am (UTC)(link)
более высокий их средний уровень дает ложное ощущение собственной профессиональной крутости, со всеми вытекающими.

[identity profile] nvm.livejournal.com 2008-06-25 12:51 pm (UTC)(link)
юзерпик клёвый

[identity profile] qehgt.livejournal.com 2008-06-25 12:05 pm (UTC)(link)
Просто A2 - тролль.

[identity profile] qehgt.livejournal.com 2008-06-25 12:07 pm (UTC)(link)
Другой вопрос, что использовать exceptions в коде, который всякими семаформами/мьютексами лочится - это себе грабли раскладывать.

[identity profile] psilogic.livejournal.com 2008-06-25 12:17 pm (UTC)(link)
Да это без разницы - с таким же успехом можно забыть разлочить перед return. Сунуть разлочивание в деструктор мутекса - и спать спокойно...

[identity profile] qehgt.livejournal.com 2008-06-25 12:47 pm (UTC)(link)
Да, обычно так и поступают.

В результате исключение выйдет из функции и прибьёт working thread, а с ней и всю программу. Зато мьютекс перед этим разлочили, да.

Разговор (меня, наверное, не поняли) о том, что исключения подходят для ситуаций "проблема возникла здесь, но решать её будем на другом, более высоком уровне. А сейчас - освободим все выделенные локально ресурсы и выйдем из функции". А когда появляются семафоры/мьютексы - работа идёт в нескольких нитях, а нормального механизма обрабатывать исключительные ситуации, которые возникают в "другой" нити - нет.

[identity profile] metaclass.livejournal.com 2008-06-25 01:03 pm (UTC)(link)
Исключения в фоновых потоках программу не убивают, если там конечно не массовое повреждение памяти. Просто поток тихо умирает и все, во всяком случае, в дельфи так.
В .net точно не помню, вроде бы обработчик исключения по умолчанию показывает сообщение, вне зависимости от потока, где оно возникло, остальные потоки при этом работают.

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

[identity profile] qehgt.livejournal.com 2008-06-25 01:32 pm (UTC)(link)
А в С++ - завершают (как это так, исключение никто не обработал?!). Но даже если и не завершали бы - вот сдохла у нас working thread, которая отвечает за какую-то нужную параллельно работающую подсистему. Всё, программа уже в нерабочем состоянии.

В результате получается, что если нам нужна гарантия работы программы/устройства, то приходится обрабатывать исключения в месте их возникновения (или максимум - не давать им выходить за пределы кода, с который взаимодействуют другие нити), что сводит их преимущества к нулю.

Но я с этого разговор начинал.

[identity profile] metaclass.livejournal.com 2008-06-25 01:35 pm (UTC)(link)
За потоками для подсистем обычно следит еще один поток-watchdog, который запускает их повторно в случае чего. И считает количество падений, при превышении заданного порога - начинает истерику, зовет админа разбираться, уведомляет по почте, итд.

[identity profile] qehgt.livejournal.com 2008-06-25 01:41 pm (UTC)(link)
Это если систему спроектировали так, что это стало возможным. Я вот, к примеру, таких не встречал.

[identity profile] ivankon.livejournal.com 2008-06-25 01:47 pm (UTC)(link)
Исключительные ситуации, которые возникают в нити, надо обрабатывать в этой же нити. Еще не хватало из нити в нить исключения кидать...

[identity profile] qehgt.livejournal.com 2008-06-25 01:55 pm (UTC)(link)
я об этом и говорю. Но тогда исключения становятся не тем, для чего они предназначались (способом обработки ошибок на другом, внешнем уровне), а банальным кодом возврата из функции. И вместо линейного кода, в котором легко видно логику работы, получается сложная нарезка из try/catch.

[identity profile] metaclass.livejournal.com 2008-06-25 02:02 pm (UTC)(link)
Исключения более удобный способ раскрутки стека вызовов при ошибке, чем коды возврата. И внешнесть уровня тут именно в том, что их не нужно перехватывать на каждом вызове, в отличие от кодов возврата. Вот try/finally для корректного освобождения делать надо, если нету каких-нибудь аналогичных методов, типа объекта-мютекса на стеке с освобождением в деструкторе в с++.

[identity profile] psilogic.livejournal.com 2008-06-25 02:46 pm (UTC)(link)
А кто вам сказал, для чего они предназначались?

[identity profile] qehgt.livejournal.com 2008-06-25 03:14 pm (UTC)(link)
One of the most powerful features of exception handling is that an error can be thrown over function boundaries. This means that if one of the deepest functions on the stack has an error, this error can propagate up to the upper function if there is a trying-block of code there. This allows programmers to put the error handling code in one place, such as the main-function of your program.

[identity profile] qehgt.livejournal.com 2008-06-25 03:18 pm (UTC)(link)
Первое же предложение в Стандарте С++, глава "Exception handling":

Exception handling provides a way of transferring control and information from a point in the execution of a program to an exception handler associated with a point previously passed by the execution

[identity profile] psilogic.livejournal.com 2008-06-25 05:08 pm (UTC)(link)
И как эта цитата связана с тем, что вы написали?

"не тем, для чего они предназначались (способом обработки ошибок на другом, внешнем уровне), а банальным кодом возврата из функции."

Вообще-то банальный код возврата из функции - это один из способов обработки ошибок на внешнем уровне (на уровне функции, которая вызвала ту функцию).

[identity profile] qehgt.livejournal.com 2008-06-25 09:25 pm (UTC)(link)
Прямо и связана. "Код возврата" проверяется на уровне N-1, а exception - хоть на N-1, хоть на N-100.

[identity profile] psilogic.livejournal.com 2008-06-25 09:48 pm (UTC)(link)
Ну код тоже можно передать через несколько уровней. Тут дело вовсе не в числе уровней, и не в передаче исключений из треда в тред. Это уже полный бред: если из-за внешнего исключения тред будет прекращать управление где попало, замучаешься предусматривать все. Дело тут в другом принципе передачи управления.

C++ исторически рождался как upgrade для C, который усовершенствует существующие возможности C.
Исключения в C++ - это наследие C-шного setjmp/longjmp. Фамильные следы происхождения можно заметить в этой фразе:

"exception handler associated with a point previously passed by the execution"

Именно так. Обработчик исключений ассоциируется с точкой, которую раньше прошли при исполнении. Это и есть setjump: когда его вызывают, то запоминается место вызова, а потом longjmp-ом происходит скачок туда через сколько угодно уровней. В C++ реализовано фактически то же самое, но намного удобнее.

[identity profile] metaclass.livejournal.com 2008-06-25 12:17 pm (UTC)(link)
Как известно, исключения используются всегда, даже если ты их сам не вызываешь. В С++, может быть, это непривычно, но в Delphi, .NET и жабе исключения могут вызвать практически любые вызываемые методы. Соответственно, их нужно всегда обрабатывать.

И многопоточная обработка с наличием исключений давным давно теоретически обоснована вдоль и поперек, нету там никаких грабель, достаточно следовать заповедям.

[identity profile] qehgt.livejournal.com 2008-06-25 12:33 pm (UTC)(link)
>достаточно следовать заповедям.
Т.е. жить в идеальном мире, где все - high-skilled developers.

И стек не портится, и память не перетирается, и dead-lock'ов не бывает.

[identity profile] metaclass.livejournal.com 2008-06-25 12:38 pm (UTC)(link)
В дотнете первых двух ошибок добится практически невозможно, а дедлоки исключаются следованием заповедям.
Вообще, изучение и следование теории спасает от многих видов программистского геморроя, хотя и делает код вида: 10% работы, 90% обработки ошибок, выводов в лог и служебных действий :)

[identity profile] vp.livejournal.com 2008-06-25 12:41 pm (UTC)(link)
и плюс еще наше любимое протоколирование "общего проядка входов-выходов" в методы (во все методы) со штампами времени. В совокупность с отладочной информацией о тех же эксепшынах в том же логе очень спасает чтоб воссоздать что же таки там грохнулось.

[identity profile] qehgt.livejournal.com 2008-06-25 12:50 pm (UTC)(link)
Я С++ ругаю. В языках без указателей и с нативной поддержкой thread многих проблем не существует как класса.

[identity profile] vp.livejournal.com 2008-06-25 12:40 pm (UTC)(link)
суть в том, чтобы на этапе проектирования отловить все взаимоблокировки и т.п. некорректщину. В финальном продукте таких костылей быть не должно, типа "в ексепные разлочивать ресурсы по списку". Свалилось - и хер с ним, лучше пусть дальше не работает.