Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Это представляет environ
как массив указателей на каждый элемент программного окружения (помните, каждый элемент — это пара ИМЯ = ЗНАЧЕНИЕ
), и финальный элемент массива содержит NULL
. Это объявление находится в , поэтому вам не обязательно объявлять его самостоятельно.
Наиболее общий способ проверки элементов окружения — это вызов getenv
, который исключает непосредственное обращение к переменной environ
.
const char *getenv(const char * name);
Единственный параметр getenv()
— это имя переменной окружения, значение которой интересует. Если переменная существует, getenv()
вернет указатель на ее значение. Если переменная не существует в текущем окружении (то есть окружении, на которое указывает environ
), функция вернет NULL
.
Linux предоставляет два способа добавления строк в программное окружение: setenv()
и putenv()
. POSIX определяет только putenv()
, что делает его более переносимым.
int putenv(const char * string);
Переданный функции параметр string
должен иметь форму ИМЯ = ЗНАЧЕНИЕ
. putenv()
добавляет переменную по имени ИМЯ
к текущему окружению и присваивает ей значение ЗНАЧЕНИЕ
. Если окружение уже содержит переменную ИМЯ
, ее значение изменяется на ЗНАЧЕНИЕ
.
BSD определяет функцию setenv()
, которую Linux также поддерживает. Это более гибкий и удобный способ добавления переменных к окружению.
int setenv(const char * name, const char * value, int overwrite);
Здесь имя и новое значение переменной окружения передаются раздельно, что обычно программам делать проще. Если overwrite
равно 0, окружение не модифицируется, если оно уже содержит переменную по имени name
. В противном случае значение переменной модифицируется, как и в putenv()
.
Ниже приведен короткий пример использования обеих функций. Оба вызова делают одно и то же, заменяя переменную окружения PATH
для запущенной программы.
putenv("PATH=/bin:/usr/bin");
setenv("PATH","/bin:/usr/bin", 1);
10.3.2 Использование ресурсов
Ядро Linux отслеживает, сколько ресурсов использует каждый процесс. Хотя отслеживается только небольшое их число, их измерения могут быть полезными разработчикам, администраторам и пользователям. В табл. 10.1 перечислены ресурсы, использование которых отслеживается ядром Linux версии 2.6.7.
Таблица 10.1. Ресурсы процессов, отслеживаемые Linux
Тип | Член | Описание |
---|---|---|
struct timeval |
ru_utime |
Общее время, затраченное на выполнение кода в режиме пользователя. Это включает в себя все время, потраченное на выполнение инструкций приложения, но исключая время, потраченное ядром на обслуживание запросов приложения. |
struct timeval |
ru_stime |
Общее время, потраченное ядром на выполнение запросов процесса. Это не включает времени блокировки процесса в период ожидания выполнения системных вызовов. |
long |
ru_minflt |
Количество второстепенных сбоев (minor faults), вызванных данным процессом. Второстепенные сбои — это попытки доступа к памяти, переключающие процессор в режим ядра, но не вызывающих обращений к диску. Это случается, когда процесс пытается писать за пределами стека, что вынуждает ядро распределить больше пространства стека, прежде чем продолжить выполнение процесса. |
long |
ru_majflt |
Количество первостепенных сбоев (major faults), вызванных данным процессом. Первостепенные сбои — это обращения к памяти, заставляющие ядро обратиться к диску, прежде чем программа сможет продолжить работу. Одной из частых причин этого может быть обращение к части исполняемой памяти, которая еще не была загружена в ОЗУ с диска либо была временно выгружена на диск. |
long |
ru_nswap |
Количество страниц памяти, для которых был выполнен обмен с диском при обращении к памяти из процесса. |
Процесс может проверять использование ресурсов им самим, общее использование ресурсов его дочерними процессами либо сумму того и другого.
Системный вызов getrusage()
возвращает структуру struct rusage
(определенную в ), содержащую информацию о текущем использовании ресурсов.
int getrusage(int who, struct rusage * usage);
Первый параметр, who
, сообщает, какой из трех счетчиков ресурсов должен быть возвращен. RUSAGE_SELF
возвращает использование ресурсов текущим процессом, RUSAGE_CHILDREN
— его дочерними процессами, a RUSAGE_BOTH
— общее использование ресурсов текущим процессом и всеми его дочерними процессами. Второй параметр getrusage()
— это указатель на struct rusage
, куда помещается информация об использовании ресурсов. Хотя struct rusage и содержит относительно немного членов (список унаследован из BSD), большинство этих членов пока не используются Linux). Ниже представлено полное определение этой структуры. В табл. 10.1 описаны члены, используемые в настоящее время Linux.
#include
struct rusage {
struct timeval ru_utime;
struct timeval ru_stime;
long intru_maxrss;
long intru_ixrss;
long intru_idrss;
long intru_isrss;
long intru_minflt;
long intru_majfit;
long intru_nswap;
long intru_inblock;
long intru_oublock;
long intru_msgsnd;
long intru_msgrcv;
long intru_nsignals;
long intru_nvcsw;
long intru_nivcsw;
};
10.3.3. Применение ограничений использования ресурсов
Чтобы помочь в предотвращении неконтролируемого снижения производительности процессами, Unix отслеживает многие ресурсы, которые может использовать процесс, и позволяет системному администратору и самим пользователям накладывать ограничения на расход ресурсов процессами.
Предусмотрены два класса доступных ограничений: жесткие и мягкие ограничения. Жесткие обычно установлены при запуске системы в RLIM_INFINITY
, что означает отсутствие каких-либо ограничений. Единственное исключение из этого — RLIMIT_CORE
(максимальный размер дампа памяти), который Linux инициирует нулем, чтобы предотвратить неожиданный сброс дампов ядра. Многие дистрибутивы сбрасывают этот лимит при запуске, однако, большинство технических пользователей ожидают появления дампов памяти при некоторых условиях (информацию о дампах памяти можно найти далее в главе). Мягкие ограничения — это те ограничения, которые установлены в ядре в данный момент. Любой процесс может наложить мягкое ограничение на использование ресурса на определенном уровне — равном или более низком, чем установленное жесткое ограничение.
Таблица 10.2. Ограничения ресурсов
Значение | Лимит |
---|---|
RLIMIT_AS |
Максимальный объем памяти, доступный процессу. Включает память для стека, глобальных переменных и динамически выделенную память. |
RLIMIT_CORE |
Максимальный размер дампа памяти, генерируемого ядром (если файл дампа получается слишком большим, он не создается). |
RLIMIT_CPU |
Общее используемое время процессора (в секундах). Более подробно об этом ограничении рассказывается при описании SIGXCPU в главе 12. |
RLIMIT_DATA |
Максимальный объем памяти данных (в байтах). Это не включает динамически выделенную память. |
RLIMIT_FSIZE |
Максимальный размер открытого файла (проверяется при записи). Более подробно об этом ограничении рассказывается при описании SIGXFSZ в главе 12. |
RLIMIT_MEMLOCK |
Максимальный объем памяти, которая может быть блокирована с помощью mlock() . Функция mlock() рассматривается в главе 13. |
RLIMIT_NOFILE |
Максимальное количество открытых файлов. |
RLIMIT_NPROC |
Максимальное количество дочерних процессов, которые может породить данный процесс. Это ограничивает только количество дочерних процессов, которые могут существовать одновременно. Это не ограничивает количества наследников дочерних процессов — каждый из них может иметь до RLIMIT_NPROC потомков. |
RLIMIT_RSS |
Максимальный объем ОЗУ, использованный в любой момент (всякое превышение этого объема используемой памяти вызывает страничную подкачку). Это также известно под названием размера резидентной части (resident set size). |
RLIMIT_STACK |
Максимальный размер памяти стека (в байтах), включая все локальные переменные. |
Различные ограничения, которые могут быть установлены, перечислены в табл. 10.2 и определены в . Системные вызовы getrlimit()
и setrlimit()
устанавливают и получают ограничения для отдельного ресурса.
Интервал:
Закладка: