Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

 pthread_attr_destroy(&attr);

 /* Тело основной программы... */

 /* Дожидаться завершения второго потока нет необходимости. */

 return 0;

}

Даже если поток был создан ожидаемым, его позднее можно сделать отсоединенным. Для этого нужно вызвать функцию

pthread_detach
. Обратное преобразование невозможно.

4.2.

Отмена потока

Обычно поток завершается при выходе из потоковой функции или вследствие вызова функции

pthread_exit
. Но существует возможность запросить из одного потока уничтожение другого. Это называется отменой, или принудительным завершением, потока.

Чтобы отменить поток, вызовите функцию

pthread_cancel
, передав ей идентификатор требуемого потока. Далее можно дождаться завершения потока. Вообще-то, это обязательно нужно делать с целью освобождения ресурсов, если только поток не является отсоединенным. Отмененный поток возвращает специальное значение
PTHREAD_CANCELED
.

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

С точки зрения возможности отмены поток находится в одном из трех состояний.

■ Асинхронно отменяемый. Такой поток можно отменить в любой точке его выполнения.

■ Синхронно отменяемый. Поток можно отменить, но не везде. Запрос на отмену помещается в очередь, и поток отменяется только по достижении определенной точки.

■ Неотменяемый. Попытки отменить поток игнорируются. Первоначально поток является синхронно отменяемым.

4.2.1. Синхронные и асинхронные потоки

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

Чтобы сделать поток асинхронно отменяемым, воспользуйтесь функцией

pthread_setcanceltype
. Эта функция влияет на тот поток, в котором она была вызвана. Первый ее аргумент должен быть
PTHREAP_CANCEL_ASYNCHRONOUS
в случае асинхронных потоков и
PTHREAD_CANCEL_DEFERRED
— в случае синхронных потоков. Второй аргумент — это указатель на переменную, в которую записывается предыдущее состояние потока.

Вот как можно сделать поток асинхронным:

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

Что такое точка отмены и где она должна находиться? На этот вопрос нельзя дать прямой ответ. Точка отмены создается с помощью функции

pthread_testcancel
. Все, что она делает, — это обрабатывает отложенный запрос на отмену в синхронном потоке. Ее следует периодически вызывать в потоковой функции в ходе длительных вычислений, там, где
поток можно завершить без риска потери ресурсов или других побочных эффектов.

Некоторые функции неявно создают точки отмены. О них можно узнать на

man
– странице, посвященной функции
pthread_cancel
. Учтите, что они могут вызываться в других функциях, которые, тем самым, косвенно станут точками отмены.

4.2.2. Неотменяемые потоки

Поток может вообще отказаться удаляться, вызвав функцию

pthread_setcancelstate
. Как и в случае функции
pthread_setcanceltype
, это оказывает влияние только на вызывающий поток. Первый аргумент функции должен быть
PTHREAD_CANCEL_DISABLE
, если нужно запретить отмену потока, и
PTHREAD_CANCEL_ENABLE
в противном случае. Второй аргумент — это указатель на переменную, в которую записывается предыдущее состояние потока.

Вот как можно запретить отмену потока:

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

Функция

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

Предположим, к примеру, что для банковской программы требуется написать функцию, осуществляющую перевод денег с одного счета на другой. Для этого нужно добавить заданную сумму на баланс одного счета и вычесть аналогичную сумму с баланса другого счета. Если между этими двумя операциями произойдет отмена потока, выполняющего функцию, программа ложно увеличит суммарный депозит банка вследствие незавершенной транзакции. Чтобы этого не случилось, обе операции должны выполняться в критической секции.

В листинге 4.6 показан пример функции

process_transaction
, осуществляющей данную задумку. Функция запрещает отмену потока до тех пор, пока баланс обоих счетов не будет изменен.

Листинг 4.6. (critical_section.c) Защита банковской транзакции с помощью критической секции

#include <pthread.h>

#include <stdio.h>

#include <string.h>

/* Массив балансов счетов, упорядоченный по номеру счета. */

float* account_balances;

/* перевод денежной суммы, равной параметру DOLLARS, со счета

FROM_ACCT на счет TO_ACCT. Возвращается 0, если транзакция

завершена успешно, или 1, если баланс счета FROM_ACCT

слишком мал. */

int process_transaction(int from_acct, int to_acct,

 float dollars) {

 int old_cancel_state;

 /* Проверяем баланс на счету FROM_ACCT. */

Поделиться:
Популярные книги

Инцел на службе демоницы 1 и 2: Секса будет много

Блум М.
Инцел на службе демоницы
Фантастика:
фэнтези
5.25
рейтинг книги
Инцел на службе демоницы 1 и 2: Секса будет много

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Жандарм 2

Семин Никита
2. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 2

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле

Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Агеева Елена А.
Документальная литература:
публицистика
5.40
рейтинг книги
Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Истребитель. Ас из будущего

Корчевский Юрий Григорьевич
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.25
рейтинг книги
Истребитель. Ас из будущего

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Отмороженный 4.0

Гарцевич Евгений Александрович
4. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Отмороженный 4.0

Треугольная шляпа. Пепита Хименес. Донья Перфекта. Кровь и песок.

Бласко Висенте Ибаньес
65. Библиотека всемирной литературы
Проза:
классическая проза
5.00
рейтинг книги
Треугольная шляпа.
Пепита Хименес.
Донья Перфекта.
Кровь и песок.

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Три `Д` для миллиардера. Свадебный салон

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
7.14
рейтинг книги
Три `Д` для миллиардера. Свадебный салон

Бастард Императора. Том 5

Орлов Андрей Юрьевич
5. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 5

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21