Основы программирования в Linux
Поле
в выводе командыPPIDсодержит ID родительского процесса (PID), либо процесса, запустившего данный процесс, либо, если этот процесс уже не выполняется, процессаps(PID, равный 1).initПланировщик процессов ОС Linux решает, какому процессу разрешить выполнение, на основе приоритета. Конкретные реализации конечно отличаются, но высокоприоритетные процессы выполняются чаще. В некоторых случаях низкоприоритетные процессы не выполняются совсем, если высокоприоритетные процессы готовы к выполнению.
Запуск новых процессов
Применив библиотечную функцию
, вы можете заставить программу выполняться из другой программы и тем самым создать новый процесс:system<b>#include <stdlib.h></b><b>int system(const char *string);</b>Функция
выполняет команду, переданную ей как строку, и ждет ее завершения. Команда выполняется, как если бы командной оболочке была передана следующая команда:system$ <b>sh -с string</b>Функция
возвращает код 127, если командная оболочка не может быть запущена для выполнения команды, и -1 в случае другой ошибки. Иначеsystemвернет код завершения команды.systemВыполните упражнение 11.1.
Упражнение 11.1. ФункцияsystemВы можете использовать
для написания программы, выполняющей командуsystem. Хотя нельзя сказать, что она необычайно полезна, вы увидите, как применять этот метод в последующих примерах. (Для простоты примера мы не проверяем, работает ли на самом деле системный вызов.)ps#include <stdlib.h>#include <stdio.h>int main() {printf("Running ps with system\n");system("ps ax");printf("Done \n");exit(0);}Когда вы откомпилируете и выполните программу system1.с, то получите вывод, похожий на приведенный далее:
$ <b>./system1</b>Running ps with systemPID TTY STAT TIME COMMAND1 ? Ss 0:03 init [5]...1262 pts/1 Ss 0:00 /bin/bash1273 pts/2 S 0:00 su -1274 pts/2 S+ 0:00 -bash1463 pts/2 SN 0:00 oclock1465 pts/1 S 0:01 emacs Makefile1480 pts/1 S+ 0:00 ./system11481 pts/1 R+ 0:00 ps axDone.Поскольку функция
применяет командную оболочку для запуска нужной программы, вы можете перевести ее в фоновый режим, заменив вызов функции в файле system1.с на следующий:systemsystem("ps ах &");Когда вы откомпилируете и выполните эту версию программы, то получите следующий вывод:
$ <b>./system2</b>Running ps with systemPID TTY STAT TIME COMMAND1 ? S 0:03 init [5]...Done.$ 1274 pts/2 3+ 0:00 -bash1463 pts/2 SN 0:00 oclock1465 pts/1 S 0:01 emacs Makefile1484 pts/1 R 0:00 ps axКак это работает
В первом примере программа вызывает функцию
со строкой "system", выполняющую программуps ах. Когда командаpsзавершается, вызовpsвозвращает управление программе. Функцияsystemможет быть очень полезной, но она тоже ограничена. Поскольку программа вынуждена ждать, пока не завершится процесс, начатый вызовомsystem, вы не можете продолжить выполнение других задач.systemВо втором примере вызов функции
вернет управление программе, как только завершится команда командной оболочки. Поскольку это запрос на выполнение программы в фоновом режиме, командная оболочка вернет управление в программу, как только будет запущена программаsystem, ровно то же, что произошло бы при вводе в строку приглашения командной оболочки командыps$ <b>ps ах &</b>Далее программа system2 выводит
и завершается до того, как у командыDone.появится возможность отобразить до конца весь свой вывод. Выводpsпродолжает формироваться после завершения system2 и в этом случае не включает в список элемент, описывающий процессps. Такое поведение процесса может сильно сбить с толку пользователей. Для того чтобы умело применять процессы, вы должны лучше управлять их действиями. Давайте рассмотрим низкоуровневый интерфейс для создания процесса,system2.execПримечаниеВообще применение функции
— далеко не идеальный способ создания процессов, потому что запускаемая программа использует командную оболочку. Он неэффективен вдвойне: и потому что перед запуском программы запускается оболочка, и потому что сильно зависим от варианта установки командной оболочки и применяемого окружения. В следующем разделе вы увидите гораздо более удачный способ запуска программ, который почти всегда предпочтительней применения вызоваsystem.systemЗамена образа процесса
Существует целое семейство родственных функций, сгруппированных под заголовком
. Они отличаются способом запуска процессов и представлением аргументов программы. Функцияexecзамещает текущий процесс новым, заданным в аргументеexecилиpath. Функцииfileможно применять для передачи выполнения вашей программы другой программе. Например, перед запуском другого приложения с политикой ограниченного применения вы можете проверить имя пользователя и пароль. Функцииexecболее эффективны по сравнению сexec, т.к. исходная программа больше не будет выполняться после запуска новой программы.system