metaclass: (Default)
[personal profile] metaclass
отсюда

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Date: 2008-06-25 03:14 pm (UTC)
From: [identity profile] qehgt.livejournal.com
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.

Date: 2008-06-25 03:18 pm (UTC)
From: [identity profile] qehgt.livejournal.com
Первое же предложение в Стандарте С++, глава "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

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

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

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

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

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

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

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

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

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 13th, 2025 09:26 am
Powered by Dreamwidth Studios