Марк Митчелл - Программирование для Linux. Профессиональный подход

Тут можно читать онлайн Марк Митчелл - Программирование для Linux. Профессиональный подход - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Вильямс, год 2002. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Программирование для Linux. Профессиональный подход
  • Автор:
  • Жанр:
  • Издательство:
    Вильямс
  • Год:
    2002
  • Город:
    Москва
  • ISBN:
    5-8459-0243-6
  • Рейтинг:
    3.6/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Марк Митчелл - Программирование для Linux. Профессиональный подход краткое содержание

Программирование для Linux. Профессиональный подход - описание и краткое содержание, автор Марк Митчелл, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.

Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.

Программирование для Linux. Профессиональный подход - читать онлайн бесплатно полную версию (весь текст целиком)

Программирование для Linux. Профессиональный подход - читать книгу онлайн бесплатно, автор Марк Митчелл
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

/* ... */

printf("SIGUSR1 was raised %d times\n", sigusr1_count);

return 0;

}

3.4. Завершение процесса

Обычно процесс завершается одним из двух способов: либо выполняющаяся программа вызывает функцию exit(), либо функция main()заканчивается. У каждого процесса есть код завершения — число, возвращаемое родительскому процессу. Этот код передается в качестве аргумента функции exit()или возвращается функцией main().

Возможно также аварийное завершение процесса, в ответ на получение сигнала. Таковыми могут быть, например, упоминавшиеся выше сигналы SIGBUS, SIGSEGVи SIGFPE. Есть сигналы, явно запрашивающие прекращение работы процесса. В частности, сигнал SIGINTпосылается, когда пользователь нажимает . Сигнал SIGTERMпосылается процессу командной killпо умолчанию. Если программа вызывает функцию abort(), она посылает сама себе сигнал SIGABRT. Самый "могучий" из всех сигналов — SIGKILL: он приводит к безусловному уничтожению процесса и не может быть ни блокирован, ни обработан.

Любой сигнал можно послать с помощью команды kill, указав дополнительный флаг. Например, чтобы уничтожить процесс, послав ему сигнал SIGKILL, воспользуйтесь следующей командой:

% kill -KILL идентификатор_процесса

Для отправки сигнала из программы предназначена функция kill(). Ее первым аргументом является идентификатор процесса. Второй аргумент — номер сигнала (стандартному поведению команды killсоответствует сигнал SIGTERM). Например, если переменная child_pidсодержит идентификатор дочернего процесса, то следующая функция, вызываемая из родительского процесса, вызывает завершение работы потомка:

kill(child_pid, SIGTERM);

Для использования функции kill()необходимо включить в программу файлы и .

По существующему соглашению код завершения указывает на то, успешно ли выполнилась программа. Нулевой код говорит о том, что все в порядке, ненулевой код свидетельствует об ошибке. В последнем случае конкретное значение кода может подсказать природу ошибки. Подобным образом функционируют все компоненты GNU/Linux. Например, на это рассчитывает интерпретатор команд, когда в командных сценариях вызовы программ объединяются с помощью операторов &&(логическое умножение) и ||(логическое сложение) Таким образом, функция main()должна явно возвращать 0 при отсутствии ошибок.

Помните о следующем ограничении: несмотря на то что тип параметра функции exit(), как и тип возвращаемого значения функции main(), равен int, операционная система Linux записывает код завершения лишь в младший из четырех байтов. Это означает, что значение кода должно находиться в диапазоне от 0 до 127. Коды, значение которых больше 128, интерпретируются особым образом: когда процесс уничтожается вследствие получения сигнала, его код завершения равен 128 плюс номер сигнала.

3.4.1. Ожидание завершения процесса

Читатели, запускавшие программу fork-exec(см. листинг 3.4), должно быть, обратили внимание на то, что вывод команды lsчасто появляется после того, как основная программа уже завершила свою работу. Это связано с тем, что дочерний процесс, в котором выполняется команда ls, планируется независимо от родительского процесса. Linux — многозадачная операционная система, процессы в ней выполняются одновременно, поэтому нельзя заранее предсказать, кто — предок или потомок — завершится раньше.

Но бывают ситуации, когда родительский процесс должен дождаться завершения одного или нескольких своих потомков. Это можно сделать с помощью функций семейства wait(). Они позволяют родительскому процессу получать информацию о завершении дочернего процесса. В семейство входят четыре функции, различающиеся объемом возвращаемой информации, а также способом задания дочернего процесса.

3.4.2. Системные вызовы wait()

Самая простая функция в семействе называется wait(). Она блокирует вызывающий процесс до тех пор, пока один из его дочерних процессов не завершится (или не произойдет ошибка). Код состояния потомка возвращается через аргумент, являющийся указателем на целое число. В этом коде зашифрована различная информация о потомке. Например, макрос WEXITSTATUS()возвращает код завершения дочернего процесса. Макрос WIFEXITED()позволяет узнать, как именно завершился процесс: обычным образом (с помощью функции exit()или оператора returnфункции main()) либо аварийно вследствие получения сигнала. В последнем случае макрос WTERMSIG()извлекает из кода завершения номер сигнала.

Ниже приведена доработанная версия функции main()из файла fork-exec.c. На этот раз программа вызывает функцию wait(), чтобы дождаться завершения дочернего процесса, в котором выполняется команда ls.

int main() {

int child_status;

/* Список аргументов, передаваемых команде ls. */

char* arg_list[] = {

"ls", /* argv[0] — имя программы. */

"-l",

"/",

NULL /* Список аргументов должен оканчиваться указателем

NULL. */

};

/* Порождаем дочерний процесс, который выполняет команду ls.

Игнорируем возвращаемый идентификатор дочернего процесса. */

spawn("ls*, arg_list);

/* Дожидаемся завершения дочернего процесса. */

wait(&child_status);

if (WTFEXITED(child_status));

printf("the child process exited normally, with exit code %d\n",

WEXITSTATUS(child_status));

else

printf("the child process exited abnormally\n");

return 0;

}

Расскажем о других функциях семейства. Функция waitpid()позволяет дождаться завершения конкретного дочернего процесса, а не просто любого. Функция wait3()возвращает информацию о статистике использования центрального процессора завершившимся дочерним процессом. Функция wait4()позволяет задать дополнительную информацию о том, завершения каких процессов следует дождаться.

3.4.3. Процессы-зомби

Если дочерний процесс завершается в то время, когда родительский процесс заблокирован функцией wait(), он успешно удаляется и его код завершения передается предку через функцию wait(). Но что произойдет, если потомок завершился, а родительский процесс так и не вызвал функцию wait()? Дочерний процесс просто исчезнет? Нет, ведь в этом случае информация о его завершении (было ли оно аварийным или нет и каков код завершения) пропадет. Вместо этого дочерний процесс становится процессом-зомби.

Зомби — это процесс, который завершился, но не был удален. Удаление зомби возлагается на родительский процесс. Функция wait()тоже это делает, поэтому перед ее вызовом не нужно проверять, продолжает ли выполняться требуемый дочерний процесс. Предположим, к примеру, что программа создает дочерний процесс, выполняет нужные вычисления и затем вызывает функцию wait(). Если к тому времени дочерний процесс еще не завершился, функция wait()заблокирует программу. В противном случае процесс на некоторое время превратится в зомби. Тогда функция wait()извлечет код его завершения, система удалит процесс и функция немедленно завершится.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Марк Митчелл читать все книги автора по порядку

Марк Митчелл - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Программирование для Linux. Профессиональный подход отзывы


Отзывы читателей о книге Программирование для Linux. Профессиональный подход, автор: Марк Митчелл. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x