Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Цилюрик О.И. Linux-инструменты для Windows-программистов
Назад Библиотеки API POSIX Вперед

Завершение потока

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

  • Сам поток вызывает pthread_exit(), и завершается со статусом завершения, доступным другому потоку по вызову ожидания pthread_join();
  • Поток осуществляет возврат из функции потока, это эквивалентно pthread_exit(), возвращаемое значение является кодом возврата;
  • Поток завершается по pthread_cancel() (это отдельный вопрос, рассматриваемый далее);
  • Какой либо поток процесса вызывает exit(), или сама главная программа main завершается — все порождённые потоки процесса также завершаются.

Это вызывается в потоке при его завершении:

void pthread_exit( void *retval );

А это — в вызывающем потоке, ожидающем завершения:

int pthread_join( pthread_t th, void **return );

Детально поведение потока при завершении определяется ещё одной группой параметров, задаваемых в атрибутной записи потока pthread_attr_t:

enum { /* Cancellation — состояние завершаемости */ 
  PTHREAD_CANCEL_ENABLE,
  PTHREAD_CANCEL_DISABLE
}; 
enum { /* тип завершаемости */
  PTHREAD_CANCEL_DEFERRED,
  PTHREAD_CANCEL_ASYNCHRONOUS
}; 

И соответствующие API:

int pthread_setcancelstate( int state, int *oldstate );

int pthread_setcanceltype( int type, int *oldtype);

Отметка очередной точки отмены потока:

void pthread_testcancel( void );

Отменить поток немедленно, или при ближайшей возможности:

int pthread_cancel( pthread_t th );

И, наконец, последнее: стек процедур завершения.

void pthread_cleanup_push( void(*routine)(void*), void *arg );

void pthread_cleanup_push( int exec );

Примечание: На самом деле такие вызовы определены как макросы, что не меняет техники их использования:

#define pthread_cleanup_push( routine, arg )

#define pthread_cleanup_pop( execute )

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


Предыдущий раздел: Оглавление Следующий раздел:
Операции в потоке   Данные потока