Самьюэл Алекс
Шрифт:
Во многих случаях поток выполняет код, который нельзя просто взять и прервать. Например, поток может выделить какие-то ресурсы, поработать с ними, а затем удалить. Если отмена потока произойдет где-то посередине, освободить занятые ресурсы станет невозможно, вследствие чего они окажутся потерянными для системы. Чтобы учесть эту ситуацию, поток должен решить, где и когда он может быть отменен.
С точки зрения возможности отмены поток находится в одном из трех состояний.
■ Асинхронно отменяемый. Такой поток можно отменить в любой точке его выполнения.
■ Синхронно отменяемый. Поток можно отменить, но не везде. Запрос на отмену помещается в очередь, и поток отменяется только по достижении определенной точки.
■ Неотменяемый. Попытки отменить поток игнорируются. Первоначально поток является синхронно отменяемым.
4.2.1. Синхронные и асинхронные потоки
Асинхронно отменяемый поток "свободен" в любое время. Синхронно отменяемый поток, наоборот, бывает "свободным", только когда ему "удобно". Соответствующие места в программе называются точками отмены. Запрос на отмену помещается в очередь и находится в ней до тех пор, пока поток не достигнет следующей точки отмены.
Чтобы сделать поток асинхронно отменяемым, воспользуйтесь функцией
Вот как можно сделать поток асинхронным:
Что такое точка отмены и где она должна находиться? На этот вопрос нельзя дать прямой ответ. Точка отмены создается с помощью функции
Некоторые функции неявно создают точки отмены. О них можно узнать на
4.2.2. Неотменяемые потоки
Поток может вообще отказаться удаляться, вызвав функцию
Вот как можно запретить отмену потока:
Функция
Предположим, к примеру, что для банковской программы требуется написать функцию, осуществляющую перевод денег с одного счета на другой. Для этого нужно добавить заданную сумму на баланс одного счета и вычесть аналогичную сумму с баланса другого счета. Если между этими двумя операциями произойдет отмена потока, выполняющего функцию, программа ложно увеличит суммарный депозит банка вследствие незавершенной транзакции. Чтобы этого не случилось, обе операции должны выполняться в критической секции.
В листинге 4.6 показан пример функции