Создание программ с несколькими нитями ненамного сложнее разработки программ, распадающихся на несколько процессов. Подробное описание библиотеки для работы с нитями приведено в разделе Глава 11, Создание программ с нитями. К процессу разработки программ относятся также компиляция и отладка программы.
Более подробно разработка многонитевых программ описывается в следующих разделах:
Этот раздел посвящен компиляции программ с несколькими нитями. В нем обсуждаются следующие вопросы:
Все прототипы процедур, макросы и другие определения, необходимые для работы с библиотекой нитей, собраны в один файл заголовков pthread.h, расположенный в каталоге /usr/include.
Файл заголовков
pthread.h должен включаться первым во все исходные файлы,
работающие с библиотекой нитей, так как в этом файле заголовка определяется
несколько важных макросов, влияющих на другие файлы заголовков. Если
файл заголовка pthread.h указан первым, будут применяться
функции с защитой нитей. В файле заголовка pthread.h
определяются следующие глобальные символы:
В файле pthread.h глобальная переменная errno переопределяется на функцию, возвращающую значение errno для конкретной нити. Следовательно, идентификатор errno в программах с несколькими нитями не является значением типа l-value.
Для компиляции программы с
несколькими нитями нужно вызвать компилятор C с помощью одной из следующих
команд:
xlc_r | Вызов компилятора с языком по умолчанию ansi. |
cc_r | Вызов компилятора с языком по умолчанию extended. |
Эти команды гарантируют, что выбранные опции и библиотеки будут соответствовать стандарту X/Open версии 5. Спецификация нитей POSIX 1003.1c представляет собой часть спецификации X/Open.
При вызове указанных выше команд к программе автоматически подключаются
следующие библиотеки:
libpthreads.a | Библиотека нитей |
libc.a | Стандартная библиотека C |
Например, приведенная ниже команда компилирует исходный файл программы с несколькими нитями на языке C (foo.c) и создает исполняемый файл foo:
cc_r -o foo foo.c
AIX поддерживает приложения, созданные в соответствии с проектом 7. Мы рекомендуем разработчикам обновить эти приложения в соответствии с современными стандартами, которые поддерживаются указанными выше компиляторами.
Для компиляции программы с несколькими нитями на уровне проекта 7 нужно
вызвать компилятор языка С с помощью одной из следующих команд:
xlc_r7 | Вызов компилятора с языком по умолчанию ansi. |
cc_r7 | Вызов компилятора с языком по умолчанию extended. |
При вызове указанных выше команд к программе автоматически подключаются
следующие библиотеки:
libpthreads_compat.a | Библиотека нитей, совместимая с проектом 7. |
libpthreads.a | Библиотека нитей |
libc.a | Стандартная библиотека C |
Совместимость исходного кода обеспечивается за счет директивы компилятора _AIX_PTHREADS_D7. Библиотеки должны быть подключены в следующем порядке: libpthreads_compat.a, libpthreads.a и libc.a. Большинство пользователей могут не вникать в эти подробности, так как описанные выше команды автоматически обеспечивают выполнение указанных требований. Эта информация предназначена для тех, кто не располагает последней версией компилятора AIX.
Окончательный вариант стандарта лишь незначительно отличается от проекта 7.
Незначительно отличаются значения errno. В окончательном варианте стандарта в ситуации, когда указанная нить не найдена, возвращается значение ESRCH. В проекте 7 в той же ситуации часто возвращалось значение EINVAL.
Все нити по умолчанию поддерживают функцию стыковки. Обратите на это внимание, так как в противном случае память в программе будет расходоваться неэффективно. Дополнительная информация о создании нитей приведена в разделе Создание нитей.
По умолчанию все нити имеют локальную область действия. Дополнительная информация о планировании приведена в разделе Планирование работы нитей.
Процедура pthread_yield заменена на процедуру sched_yield.
Внесены небольшие изменения в стратегии планирования, связанные с взаимными блокировками.
В одном процессе AIX может быть создано до 32768 нитей. Для каждой нити необходимо выделить отдельную область адресного пространства процесса, так что в действительности максимальное допустимое число нитей в рамках одного процесса зависит от модели организации памяти и от объема адресного пространства процесса, используемого для других целей. Объем адресного пространства, отведенный для нити, содержит стек, защищенную область памяти и небольшой сегмент памяти для внутреннего использования. Пользователь может изменить размер стека с помощью функции pthread_attr_setstacksize(), а размер защищенной области - с помощью функции pthread_attr_setguardsize() . В приведенной ниже таблице указано максимальное число нитей, которые может создать в рамках 32-разрядного процесса простая программа, создающая в цикле новые нити с атрибутом NULL и не выполняющая никаких других действий. В реальных программах максимальное число нитей зависит от объема памяти, который используется программой для других целей. Для 64-разрядных процессов максимальное число нитей процесса зависит от параметра ulimit, поэтому модель большого адресного пространства может только уменьшить максимальное число нитей.
32-разрядный процесс:
Модель данных | -bmaxdata: | Максимальное число нитей |
---|---|---|
Небольшой объем данных | н/д | 1084 |
Большой объем данных | 0x10000000 | 2169 |
Большой объем данных | 0x20000000 | 4340 |
Большой объем данных | 0x30000000 | 6510 |
Большой объем данных | 0x40000000 | 8681 |
Большой объем данных | 0x50000000 | 10852 |
Большой объем данных | 0x60000000 | 13022 |
Большой объем данных | 0x70000000 | 15193 |
Большой объем данных | 0x80000000 | 17364 |
В этом разделе приведены основные сведения об отладке программ с несколькими нитями.
Программа dbx предназначена для отладки приложений. Были добавлены следующие подкоманды для просмотра объектов, связанных с нитями: attribute, condition, mutex и thread.
Для отладки расширений ядра и драйверов устройств можно применять отладчик ядра. Эта программа не позволяет работать с пользовательскими нитями, она работает только с нитями ядра.
Для поддержки нескольких нитей ядра и нескольких процессоров были добавлены следующие команды: cpu, ppd, thread и uthread. Эти команды предназначены для изменения текущего процессора, просмотра структур данных конкретного процессора, записей таблицы нитей и структуры uthread той или иной нити.
По умолчанию процессы не создают полный дамп. До версии 4.3 в файл дампа AIX помещался только стек нити, запросившей создание дампа. В версиях AIX младше 4.3.2 в файл дампа не помещался общий сегмент памяти из адресного пространства процесса. Если при отладке необходимо просмотреть данные из общего сегмента памяти или из стека нити, нужно создать полный дамп. Для этого вызовите следующую команду (права на ее выполнения есть только у пользователя root):
chdev -l sys0 -a fullcore=true
Размер файла дампа пропорционален числу нитей. В файл дампа записываются стеки всех нитей, размер которых можно изменить с помощью функции pthread_attr_setstacksize() . Информация о нити, созданной с атрибутом NULL, занимает в файле дампа 128 Кб для 32-разрядных процессов и 256 Кб для 64-разрядных.
Глава 9, Параллельное программирование
Рекомендации по созданию программ с нитями
Написание реентерабельных программ и программ с защитой нитей