Атрибуты потоков
Создавая новый поток, вы можете указать ряд дополнительных атрибутов, определяющих некоторые его параметры. Из всех этих атрибутов более всего востребован атрибут DETACHED, позволяющий создавать отделенные потоки. Во всех рассмотренных выше примерах мы использовали функцию pthread_join(), позволяющую дождаться завершения потока и получить значение, возвращенное его функцией. Для того чтобы функция pthread_join() могла получить значение функции потока, завершившегося до вызова pthread_join(), система сохраняет данные о потоке после его завершения (это похоже на появления «зомби» после завершения самостоятельного процесса). Если наша программа интенсивно работает с потоками и синхронизация потоков с помощью pthread_join() нам не нужна, мы можем сэкономить ресурсы системы, используя отделенные потоки. Отделенные потоки отличаются от обычных (присоединяемых) потоков тем, что после завершения отделенного потока система не сохраняет информацию о нем. Если вызвать функцию pthread_join() для отделенного потока, она вернет сообщение об ошибке.
Вы можете превратить присоединяемый поток в отделенный с помощью вызова функции pthread_detach(3), однако придать потоку свойство «отделенности» можно и на этапе его создания, с помощью дополнительного атрибута DETACHED. Для того чтобы назначить потоку дополнительные атрибуты, нужно сначала создать объект, содержащий набор атрибутов. Этот объект создается функцией pthread_attr_init(3). Единственный аргумент этой функции – указатель на переменную типа pthread_attr_t, которая служит идентификатором набора атрибутов. Функция pthread_attr_init() инициализирует набор атрибутов потока значениями, заданными по умолчанию, так что мы можем модифицировать только те атрибуты, которые нас интересуют, и не беспокоиться об остальных. Для добавления атрибутов в набор используются специальные функции с именами pthread_attr_set. Например, для того, чтобы добавить атрибут «отделенности», мы вызываем функцию pthread_attr_setdetachstate(3). Первым аргументом этой функции должен быть адрес объекта набора атрибутов, а вторым аргументом – константа, определяющая значение атрибута. Константа PTHREAD_CREATE_DETACHED указывает, что создаваемый поток должен быть отделенным, тогда как константа PTHREAD_CREATE_JOINABLE определяет создание присоединяемого (joinable) потока, который может быть синхронизирован функций pthread_join(3). После того, как мы добавили необходимые значения в набор атрибутов потока, мы вызываем функцию создания потока pthread_create(). Набор атрибутов потока передается в качестве второго аргумента этой функции.
На этом мы закончим ликбез, посвященный потокам. Если вы любите потоки также сильно, как люблю их я, к вашим услугам неисчерпаемое море специальной литературы (например, книга Ричарда Стивенса) и страницы man, в которых вы найдете все то, чему не хватило места на страницах журнала. Ну а перед тем, как приступать к чтению следующей статьи этой серии, запаситесь серой, ибо мы познакомимся с демонами.