Windows для профессионалов


Программа-пример Summation - часть 2


Затем его функция инициализирует переменную uSum значением UINT_MAX, т.e. изначально предполагается, что работа функции не завершится успехом. Далее SumThreadFunc активизирует SEH так, чтобы перехватывать любое исключение, возникающее при выполнении потока. После чего для вычисления суммы вызывается рекурсивная функция Sum.

Если сумма успешно вычислена, SumThreadFunc просто возвращает значение переменной uSum, оно и будет кодом завершения потока. Но, если при выполнении Sum возникает исключение, система сразу оценивает выражение в фильтре исключений. Иначе говоря, система вызывает FilterFunc, передавая ей код исключения. R случае переполнения стека этим кодом будет EXCEPTION_STACK_OVERFLOW. Чтобы увидеть, как программа обрабатывает исключение, вызванное переполнением стека, дайте ей просуммировать числа от 0 до 44000.

Моя функция FilterFunc очень проста. Сначала она проверяет, произошло ли исключение, связанное с переполнением стека. Если нет, возвращает EXCEPTION_CONTINUE_SEARCH, а если да — EXCEPTION_EXECUTE_HANDLER. Это подсказывает системе, что фильтр готов к обработке этого исключения и что надо выполнить код в блоке except. В данном случае обработчик исключения ничего особенного не делает, просто закрывая поток с кодом завершения UINT_MAX. Родительский поток, получив это специальное значение, выводит пользователю сообщение с предупреждением.

И последнее, что хотелось бы обсудить; почему я выделил функцию Sum в отдельный поток вместо того, чтобы просто создать SEH-фрейм в первичном потоке и вызывать Sum из его блока try. На то есть три причины.

Во-первых, всякий раз, когда создается поток, он получает стек размером 1 Мб. Если бы я вызывал Sum из первичного потока, часть стекового пространства уже была бы занята, и функция не смогла бы использовать весь объем стека. Согласен, моя программа очень проста и, может быть, не займет слишком большое стековое пространство. А если программа посложнее? Легко представить ситуацию, когда Sum подсчитывает сумму целых чисел от 0 до 1000 и стек вдруг оказывается чем-то занят, — тогда его переполнение произойдет, скажем, еще при вычислении суммы от 0 до 750.


Начало  Назад  Вперед