6.3.3 Завершение потока |
Предыдущая Содержание Следующая |
Как один поток может прекратить выполнение другого потока? В нашем примере плеера после завершения воспроизведения основной поток должен остановить поток декодера перед тем, как приложение завершит работу. Это достигается с помощью функции pthread_cancel.
int pthread_cancel(pthread_t thread_id);
pthread_cancel посылает запрос на завершение потока thread_id. В нашем плеере основной поток вызывает функцию pthread_cancel, чтобы отправить запрос на остановку потока декодера, и ждёт перед выходом его завершения.
int main(){ ... ... pthread_cancel(decoder_tid); <-- посылаем запрос на завершение pthread_join(decoder_tid, NULL); }
Поток, который получает запрос на прекращение работы, может проигнорировать его, выполнить его немедленно, или отложить выполнение запроса. Чтобы определить, какое действие выполняется, когда потоком получен запрос на прекращение работы, существуют две функции:
int pthread_setcancelstate(int state, int *oldstate); int pthread_setcanceltype(int type, int *oldtype);
pthread_setcancelstate вызывается, чтобы проигнорировать или принять запрос на завершение. Запрос игнорируется, если аргументом state является PTHREAD_CANCEL_DISABLE. Завершение разрешено, если state имеет значение PTHREAD_CANCEL_ENABLE. Если завершение разрешено, вызывается pthread_setcanceltype, чтобы установить либо немедленный, либо отложенный тип завершения. Завершение выполняется немедленно, если аргумент type имеет значение PTHREAD_CANCEL_ASYNCHRONOUS. Если type имеет значение PTHREAD_CANCEL_DEFERRED, запрос на завершение откладывается до следующей точки завершения. По умолчанию поток всегда начинает работать с разрешённым завершением и с отложенным типом завершения. В примере плеера поток декодера вызывает функцию pthread_setcanceltype, чтобы установить завершение немедленного типа.
void* audio_decoder(void *unused){ ... ... pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); ... }
Как уже упоминалось ранее, выполнение запроса на завершение может быть отложено до следующей точки завершения. Так что же это за точки завершения? Точками завершения являются такие функции, где выполняется проверка на наличие ожидающего обработки запроса на завершение. Если такой запрос ждёт обработки, завершение выполняется сразу же. В общем случае любая функция, которая приостанавливает выполнение текущего потока в течение длительного времени, должна быть точкой завершения. Такие функции для работы с pthread, как pthread_join, pthread_cond_wait, pthread_cond_timedwait и pthread_testcancel служат точками завершения. Пожалуйста, обратите внимание, что выполнение запроса завершения в любой данной точке эквивалентно вызову в данной точке pthread_exit(PTHREAD_CANCELED). Поток может проверить, есть ли ожидающий обработки запрос на завершение, вызвав функцию pthread_testcancel.
void pthread_testcancel(void);
Завершение выполняется сразу же, если запрос на завершение находится в состоянии ожидания обработки, когда вызывается эта функция.
|
Предыдущая Содержание Следующая |