Управляющий поток в программе 4.4 сначала создает три рабочих потока, затем делает запрос на аннулирование каждого из них. Управляющий поток для каждого рабочего потока вызывает функцию pthread_join(). Эта функция завершается успешно даже тогда, когда она пытается присоединить поток, который уже завершен, функция присоединения в этом случае просто считывает статус завершения завершенного потока. И такое поведение весьма кстати, поскольку поток, который сделал запрос на аннулирование, и поток, вызвавший функцию pthread_join (), могут оказаться совсем разными потоками. Мониторинг функционирования всех рабочих потоков может оказаться единственной задачей того потока, который «по совместительству» и аннулирует потоки. Опрашивать же статус завершения потоков с помощью функции pthread_join() может совершенно другой поток. Этот тип информации используется для получения статистической оценки того, какой из потоков наиболее эффективен. В рассматриваемой нами программе все это делает один управляющий поток: в цикле он и присоединяет рабочие потоки, и проверяет их статус завершения. Поток Threads[0] не аннулирован, поскольку он имеет запрет на аннулирование, в то время как два остальных потока были аннулированы. Статус завершения аннулируемого потока может иметь, например, значение PTHREAD_CANCELED. Профили программ 4.3 и 4.4 представлены в разделе «Профиль программы 4.2».
Профиль программы 4.2
Имя программы program4-34. cc ;
Описание Демонстрирует аннулирование потоков. Три потока имеют различные типы состояния аннулирования. Каждый поток выполняет цикл. Состояние и тип аннулирования определяет количество итераций цикла и то, будет ли цикл выполняться вообще. Основной поток определяет статус завершения каждого , рабочего потока.
Требуемая библиотека libpthread
Тр ебуемые заголовки
Инструкции по компиляции и компоновке программ
с++ -о program4-34 program4-34.сс -lpthread
Среда для тестирования SuSE Linux 7.1, gcc 2.95.2.
И нс трукции по выполнению ./program4-34
В функциях, определенных пользователем, используются точки аннулирования отмеченные обращением к функции pthread_testcancel(). Библиотека Pthread определяет в качестве точек аннулирования выполнение других функций. Эти функции блокируют вызывающий поток, а заблокированному потоку аннулирование не грозит. Вот эти функции библиотеки Pthread:
pthread_testcancel()
pthread_cond_wait()
pthread_timedwait()
pthread_join()
Если поток, пребывающий в состоянии отсроченного аннулирования, имеет ждущий запрос на аннулирование, то при вызове одной из перечисленных выше функций библиотеки Pthread будет инициирована процедура аннулирования. Некоторые из системных функций, претендующих на роль точек аннулирования, перечислены в табл. 4.6.
Таблица 4.6. Системные POSIX-функции, претендующие на роль точек аннулирования
accept() | nanosleep() | sem_wait() |
aio_suspend() | open() | send() |
clock_nanosleep() | pause() | sendmsg() |
close() | poll() | sendto() |
connect() | pread() | sigpause() |
creat() | pthread_cond_timedwait() | sigsuspend() |
fcntl() | pthread_cond_wait() | sigtimedwait() |
fsync() | pthread_join() | sigwait() |
getmsg() | putmsg() | sigwaitinfo() |
lockf() | putpmsg() | sleep() |
mq_receive() | pwrite() | system() |
mq_send() | read() | usleep() |
mq_timedreceive() | readv() | wait() |
mq_timedsend () | recvfrom() | waitpid() |
msgrcv() | recvmsg() | write() |
msgsnd() | select() | writev() |
msync() | sem_timedwait() |
Несмотря на то что эти функции безопасны для отсроченного аннулирования потоков, они могут не быть таковыми для асинхронного аннулирования. Асинхронное аннулирование во время вызова библиотечной функции, которая не является асин хронно-безопасной, может привести к тому, что библиотечные данные останутся не в надлежащем состоянии. Библиотека выделит память от имени потока, и, когда поток будет аннулирован, продолжит удерживать «за собой» эту память. Для других библиотечных и системных функций, которые не являются безопасными для аннулирования (асинхронного или отсроченного), возможно, имеет смысл написать код, препятствующий завершению потока путем установки категорического запрета на аннулирование или использование отсроченного аннулирования до тех пор, пока эти функции не будут выполнены.
Очистка перед завершением