Программа, показанная в листинге 3.4, отображает содержимое корневого каталога с помощью команды ls
, как и программа в листинге 3.2. Но на этот раз команда ls
вызывается не из интерпретатора, а напрямую; ей передаются аргументы -l
и /
.
fork()
и exec()
#include
#include
#include
#include
/* Запуск дочернего процесса в виде новой программы. Параметр
PROGRAM — это имя вызываемой программы; ее поиск будет
осуществляться в каталогах, определяемых переменной среды PATH.
Параметр ARG_LIST -- это список строковых аргументов,
передаваемых программе (должен оканчиваться указателем NULL).
Функция возвращает идентификатор порожденного процесса. */
int spawn(char* program, char** arg_list) {
pid_t child_pid;
/* Создание копии текущего процесса. */
child_pid = fork();
if (child_pid != 0)
/* Это родительский процесс. */
return child_pid;
else {
/* Выполнение указанной программы. */
execvp(program, arg_list);
/* Функция execvp() возвращает значение только в случае
ошибки. */
fprintf(stderr, "an error occurred in execvp\n");
abort();
}
}
int main() {
/* Список аргументов, передаваемых команде ls. */
char* arg_list[] = {
"ls", /* argv[0] -- имя программы. */
"-l",
NULL /* Список аргументов должен оканчиваться указателем
NULL. */
};
/* Порождаем дочерний процесс, который выполняет команду ls.
Игнорируем возвращаемый идентификатор дочернего процесса. */
spawn("ls", arg_list);
printf("done with main program\n");
return 0;
}
3.2.3. Планирование процессов
Операционная система Linux планирует работу родительских и дочерних процессов независимо друг от друга. Нет гарантии, что один процесс будет запущен раньше другого. и неизвестно, как долго один процесс будет выполняться, прежде чем Linux прервет его работу и передаст управление другому процессу. В частности, к моменту завершения родительского процесса может оказаться, что команда ls
еще не выполнена, выполнена частично или уже закончила свою работу.[11] Linux лишь гарантирует, что любой процесс когда-нибудь получит свой "кусочек пирога": ни один процесс не окажется полностью лишенным доступа к процессору.
Можно сообщить системе о том, что процесс не очень важен и должен выполняться с пониженным приоритетом. Это делается путем повышения
Для запуска программы с ненулевым фактором уступчивости необходимо воспользоваться командой nice -n
. Рассмотрим следующий пример:
% nice -n 10 sort input.txt > output.txt
Здесь активизируется длительная операция сортировки, которая, благодаря пониженному приоритету, не приведет к сильному снижению производительности системы. Изменить фактор уступчивости выполняющегося процесса позволяет команда renice
.
Если требуется менять фактор уступчивости программным путем, воспользуйтесь функцией nice()
. Ее аргумент — это величина приращения, добавляемая к фактору уступчивости вызывающего процесса. В результате приоритет процесса снижается.
Только программа с привилегиями пользователя root
может запускать процессы с отрицательным фактором уступчивости или понижать это значение у выполняющегося процесса. Это означает, что вызывать команды nice
и renice
с отрицательными аргументами можно, лишь войдя в систему как пользователь root, и только процесс, выполняемый от имени суперпользователя, может передавать функции nice()
отрицательное значение. Таким образом, обычные пользователи не могут помешать работать процессам других пользователей и монополизировать системные ресурсы.
3.3. Сигналы