- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Параллельное и распределенное программирование на С++ - Хьюз Камерон
Шрифт:
Интервал:
Закладка:
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()
Несмотря на то что эти функции безопасны для отсроченного аннулирования потоков, они могут не быть таковыми для асинхронного аннулирования. Асинхронное аннулирование во время вызова библиотечной функции, которая не является асин хронно-безопасной, может привести к тому, что библиотечные данные останутся не в надлежащем состоянии. Библиотека выделит память от имени потока, и, когда поток будет аннулирован, продолжит удерживать «за собой» эту память. Для других библиотечных и системных функций, которые не являются безопасными для аннулирования (асинхронного или отсроченного), возможно, имеет смысл написать код, препятствующий завершению потока путем установки категорического запрета на аннулирование или использование отсроченного аннулирования до тех пор, пока эти функции не будут выполнены.
Очистка перед завершением
Поток, «позволивший» себя аннулировать, прежде чем завершиться, обычно должен выполнить некоторые заключительные действия. Так, нужно закрыть файлы, привести разделяемые данные в надлежащее состояние, снять блокировки или освободить занимаемые ресурсы. Библиотека Pthread определяет механизм поведения каждого потока «в последние минуты своей жизни». С каждым потоком связывается стек очистительно-восстановительных операций (cleanup stack), который содержит указатели на процедуры (или функции), предназначенные для выполнения во время аннулирования потока. Для того чтобы поместить в этот стек указатель на процедуру, предусмотрена функция pthread_cleanup_push ().
Синопсис
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread cleanup pop(int execute);
Параметр routine представляет собой указатель на функцию, помещаемый в стек завершающих процедур. Параметр arg содержит аргумент, передаваемый этой routine -функции, которая вызывается при завершении потока с помощью функции pthread_exit (), когда поток «покоряется» запросу на аннулирование или явным образом вызывает функцию pthread__cleanup_pop () с ненулевым значением параметра execute. Функция, заданная параметром routine, не возвращает никакого значения.
Функция pthread_cleanup_pop() удаляет указатель routine -функции из вершины стека завершающих процедур вызывающего потока. Параметр execute может принимать значение 1 или 0. Если его значение равно 1, поток выполняет routine- функцию, даже если он при этом и не завершается. Поток продолжает свое выполнение с инструкции, расположенной за вызовом функции pthread_cleanup_pop(). Если значение параметра execute равно 0, указатель извлекается из вершины стека потока без выполнения routine -функции.
Необходимо позаботиться о том, чтобы для каждой функции занесения в стек (push) существовала функция извлечения из стека (pop) в пределах одной и той же лексической области видимости. Например, для функции funcA () обязательно выполнение cleanup -обработчика при ее нормальном завершении или аннулировании:
void *funcA(void *X)
{
int *Tid;
Tid = new int;
// do some work
//...
pthread_cleanup_push(cleanup_funcA,Tid);
// do some more work
//...
pthread_cleanup_pop(0);
}
Здесь функция funcA( ) помещает указатель на обработчик cleanup_funcA( ) в стек завершающих процедур путем вызова функции pthread_cleanup_push (). Каждому обращению к этой функции должно соответствовать обращение к функции pthread_cleanup_pop(). Если функции извлечения указателя из стека (pop- функции) передается значение 0, то извлечение из стека состоится, но без выполнения обработчика. Обработчик будет выполнен лишь при аннулировании потока, выполняющего функцию funcA().
Для функции funcB () также требуется cleanup -обработчик:
void *funcB(void *X)
{
int *Tid;
Tid = new int;
// do some work
//...
pthread_cleanup_push(cleanup_funcB,Tid);
// do some more work
//...
pthread_cleanup_pop(1);
}
Здесь функция funcB () помещает указатель на обработчик cleanup_funcB () в стек завершающих процедур. Отличие этого примера от предыдущего состоит в том, что функции pthread_cleanup_pop () передается параметр со значением 1, т.е. после извлечения из стека указателя на обработчик этот обработчик будет тут же выполнен. Необходимо отметить, что выполнение обработчика в данном случае состоится «при любой погоде», т.е. и при аннулировании потока, который обеспечивает выполнение функции funcB( ), и при обычном его завершении. Обработчики- «уборщики», cleanup_funcA() и cleanup_funcB (), — это обычные функции, которые можно использовать для закрытия файлов, освобождения ресурсов, разблокирования мьютексов и пр.
Управление стеком потока
Адресное пространство процесса делится на раздел кода, раздел статических данных, свободную память и раздел стеков. Стекам потоков выделяется область из стекового раздела процесса. Стек потока предназначен для хранения стекового фрейма, связанного с каждой процедурой (функцией), которая была вызвана, но еще не завершена. Стековый фрейм содержит временные переменные, локальные переменные, адреса точек возврата и любую другую дополнительную информацию, которая необходима потоку, чтобы найти «обратную дорогу» к ранее вызванным процедурам. При выходе из процедуры (функции) ее стековый фрейм извлекается из стека. Расположение фреймов в стеке схематично показано на рис. 4.12.
Предположим, что поток А (см. рис. 4.12) выполняет функцию task1 () , которая создает некоторые локальные переменные, выполняет заданную обработку, а затем вызывает функцию taskX (). При этом для функции task1 () создается стековый фрейм, который помещается в стек потока. Функция taskX () выполняет «свои» действия, создает локальные переменные, а затем вызывает функцию taskC (). Нетрудно догадаться, что стековый фрейм, созданный для функции taskX () , также помещается в стек. Функция taskC () вызывает функцию taskY() и т.д. Каждый стек должен иметь достаточно большой размер, чтобы поместить всю информацию, необходимую для выполнения всех функций потока, а также цепочки других подпрограмм, которые будут вызваны потоковыми функциями. Размером и местоположением стека потока управляет операционная система, но для установки и считывания этой информации предусмотрены методы, которые определены в объекте атрибутов потока.