Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Атрибуты потока
Когда мы начали рассматривать потоки, то не обсуждали более сложную тему — атрибуты потока. Теперь, рассказав о синхронизации потоков — ключевой теме главы, мы можем вернуться назад и остановиться на этих характеристиках потока. Существует лишь несколько атрибутов потока, которыми вы можете управлять; здесь мы собираемся обсудить только те, которые вам понадобятся, скорее всего. Подробную информацию о других атрибутах вы можете найти в интерактивном справочном руководстве.
Во всех предыдущих примерах вы должны были повторно синхронизовать потоки с помощью функции pthread_join
, прежде чем разрешить программе завершить выполнение. Это необходимо сделать, если вы хотите, чтобы один поток вернул данные другому потоку, создавшему данный. Иногда вам не нужно ни возвращать информацию из второго потока в поток main
, ни заставлять поток main
ждать этого.
Предположим, что вы создаете второй поток для записи в буфер резервной копии файла данных, который редактируется, пока поток main
продолжает обслуживать пользователя. Когда создание копии закончено, второй поток может тут же завершиться. Ему не нужно присоединяться к потоку main
.
Вы можете создать потоки, ведущие себя подобным образом. Они называются отсоединенными или обособленными потоками, и вы создаете их, изменяя атрибуты потока или вызывая функцию pthread_detach
. Поскольку мы хотим продемонстрировать атрибуты, то применим здесь первый метод.
Самая важная функция, которая вам понадобится, — pthread_attr_init
, инициализирующая объект атрибутов потока:
#include
int pthread_attr_init(pthread_attr_t *attr);
И снова 0 возвращается в случае успешного завершения и код ошибки в случае аварийного.
Есть и функция для уничтожения: pthread_attr_destroy
. Ее задача — обеспечить чистое уничтожение объекта атрибутов. После того как объект уничтожен, он не может быть использован снова до тех пор, пока не будет инициализирован повторно.
Когда вы инициализировали объект атрибутов потока, можно использовать множество дополнительных функций, с помощью которых задается поведение разных атрибутов. Далее перечислены основные из них (полный список вы можете найти в интерактивном справочном руководстве, в разделе, посвященном pthread.h), но мы рассмотрим подробно только два: detechedstate
и schedpolicy
.
#include <���рthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr,
int *detachstate);
int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int* policy);
int pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr,
struct sched_param *param);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
int pthread_attr_getinheritsched(const pthread_attr_t *attr,
int *inherit);
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
int pthread_attr_setstacksize(pthread_attr_t *attr, int scope);
int pthread_attr_getstacksize(const pthread_attr_t *attr, int* scope);
Как видите, существует лишь несколько атрибутов, которые вы можете применять, но к счастью у вас, как правило, не возникнет необходимости в использовании большинства из них.
□ detachedstate
— этот атрибут позволяет избежать необходимости присоединения потоков (rejoin). Как и большинство этих функций с префиксом _set
, эта функция принимает указатель на атрибут и флаг для определения требуемого состояния. Два возможных значения флага для функции attr_setdetachstate
— PTHREAD_CREATE_JOINABLE
и PTHREAD_CREATE_DETACHED
. По умолчанию у атрибута будет значение PTHREAD_CREATE_JOINABLE
, поэтому вы сможете разрешить двум потокам объединяться (один ждет завершения другого). Если задать состояние PTHREAD_CREATE_DETACHED
, вы не сможете вызвать функцию pthread_join
, чтобы выяснить код завершения другого потока.
□ schedpolicy
— этот атрибут управляет планированием потоков. Возможные значения — SCHED_OTHER
, SCHED_RR
и SCHED_FIFO
. По умолчанию атрибут равен SCHED_OTHER
. Два других типа планирования доступны только для процессов, выполняющихся с правами суперпользователя, поскольку они оба задают планирование в режиме реального времени, но с немного разным поведением. SCHED_RR
использует круговую или циклическую схему планирования, a SCHED_FIFO
— алгоритм "первым прибыл, первым обслужен". Оба эти алгоритма не обсуждаются в этой книге.
□ schedparam
— это напарник атрибута schedpolicy
и позволяет управлять планированием потоков, выполняющихся с типом планирования SCHED_OTHER
. Мы рассмотрим пример его применения чуть позже в этой главе.
□ inheritsched
— этот атрибут принимает одно из двух значений: PTHREAD_EXPLICIT_SCHED
и PTHREAD_INHERIT_SCHED
. По умолчанию значение атрибута PTHREAD_EXPLICIT_SCHED
, что означает планирование, явно заданное атрибутами. Если задать PTHREAD_INHERIT_SCHED
, новый поток будет вместо этого применять параметры, используемые потоком, создавшим его.
□ scope
— этот атрибут управляет способом вычисления параметров планирования потока. Поскольку ОС Linux в настоящее время поддерживает единственное значение PTHREAD_SCOPE_SYSTEM
, мы не будем рассматривать его в дальнейшем.
□ stacksize
— этот атрибут управляет размером стека при создании потока, задается в байтах. Это часть необязательного раздела стандарта и поддерживается только в тех реализациях, у которых определено значение _PTHREAD_THREAD_ATTR_STACKSIZE
. Linux по умолчанию реализует потоки со стеком большого размера, поэтому этот атрибут в ОС Linux избыточен.
Выполните упражнение 12.5.
В примере с отсоединенным или обособленным потоком thread5.c вы создаете атрибут потока, задаете состояние потока как отсоединенное и затем создаете с помощью этого атрибута поток. Теперь, когда закончится дочерний поток, он вызовет обычным образом pthread_exit
. В это время исходный поток больше не ждет созданный им поток для присоединения. В данном примере используется простой флаг thread_finished
, чтобы позволить потоку main
определить, закончился ли дочерний поток, и показать, что потоки все еще совместно используют переменные.
Интервал:
Закладка: