Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

Задания переходят из приоритетного режима в фоновый и обратно не путем изменения атрибута задания, но посредством изменения группы процессов управляющего терминала. Это изменение осуществляет именно контролирующая задания оболочка, и если новая группа процессов останавливается, оболочка вновь запускает ее, посылая сигнал «продолжить» всем членам группы процессов.

В былые времена пользователи часто использовали последовательные терминалы, соединенные с модемами, для подключения к централизованным Unix-системам на мини-компьютерах. Когда пользователь закрывал соединение (вешал трубку), линия последовательной передачи обнаруживала отсоединение, и ядро посылало сигнал «отсоединение» всем подключенным к

терминалу процессам.

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

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

9.2.2. Идентификация группы процессов:

getpgrp
и
getpgid

Для совместимости с более старыми системами POSIX предоставляет множество способов получения сведений о группе процессов:

#include <unistd.h>

pid_t getpgrp(void); /* POSIX */

pid_t getpgid(pid_t pid); /* XSI */

Функция

getpgrp
возвращает ID группы процессов текущего процесса.
getpgid
является расширением XSI. Она возвращает ID группы процессов для данного
pid
группы процессов.
pid
, равный 0, означает «группа процессов текущего процесса». Таким образом, '
getpgid(0)
' является тем же самым, что и '
getpgrp
'. При обычном программировании следует использовать
getpgrp
.

В BSD 4.2 и 4.3 также есть функция

getpgrp
, но она действует как функция POSIX
getpgid
, требуя аргумент
pid
. Поскольку современные системы поддерживают POSIX, в новом коде следует использовать версию POSIX. (Если вы думаете, что это сбивает с толку, вы правы. Несколько способов для получения одного и того же результата является обычным итогом проектирования комитетом, поскольку комитет считает, что он должен удовлетворить каждого.)

9.2.3. Установка группы процесса:

setpgid
и
setpgrp

Две функции устанавливают группу процесса:

#include <unistd.h>

int setpgid(pid_t pid, pid_t pgid); /* POSIX */

int setpgrp(void); /* XSI */

Функция

setpgrp
проста: она устанавливает ID группы процесса равной ID процесса. Это создает новую группу процессов в том же сеансе, а вызывающий функцию процесс становится лидером группы процессов.

Функция

setpgid
предназначена для использования управления заданиями. Она позволяет одному процессу устанавливать группу процесса для другого. Процесс может изменить лишь свой собственный ID группы процессов или ID группы процессов
порожденного процесса, лишь если этот порожденный процесс не выполнил еще
exec
. Управляющая заданиями оболочка делает этот вызов после
fork
как в родительском, так и в порожденном процессах. Для одного из них вызов завершается успехом, и ID группы процессов изменяется. (В противном случае нет способа гарантировать упорядочение, когда родитель может изменить ID группы процессов порожденного процесса до того, как последний выполнит
exec
. Если сначала успешно завершится вызов родителя, он может перейти на следующую задачу, такую, как обработка других заданий или управление терминалом.)

При использовании

setpgid pgid
должна быть группой существующего процесса, которая является частью текущего сеанса, фактически подключая
pid
к этой группе процессов. В противном случае
pgid
должна равняться
pid
, создавая новую группу процессов.

Имеется несколько значений для особых случаев как для

pid
, так и для
pgid
:

pid = 0 
В данном случае
setpgid
изменяет группу процессов вызывающего процесса на
pgid
. Это эквивалентно '
setpgid(getpid, pgid)
'.

pgid = 0 
Это устанавливает ID группы процессов для данного процесса равным его PID. Таким образом, '
setpgid(pid, 0)
' является тем же самым, что и '
setpgid(pid, pid)
'. Это делает процесс с PID, равным
pid
, лидером группы процессов.

Во всех случаях лидеры сеанса являются особыми; их PID, ID группы процессов и ID сеанса идентичны, a ID группы процессов лидера не может быть изменена. (ID сеанса устанавливаются посредством

setsid
, а получаются посредством
getsid
. Это особые вызовы: см. справочные страницы setsid(2) и getsid(2)).

9.3. Базовое межпроцессное взаимодействие: каналы и очереди FIFO

Межпроцессное взаимодействие (Interprocess communication — IPC) соответствует своему названию: это способ взаимодействия для двух отдельных процессов. Самым старым способом IPC на системах Unix является канал (pipe): односторонняя линия связи. Данные, записанные в один конец канала, выходят из другого конца.

9.3.1. Каналы

Каналы проявляют себя как обычные дескрипторы файлов. Без особого разбирательства вы не можете сказать, представляет ли дескриптор файла сам файл или канал. Это особенность; программы, которые читают из стандартного ввода и записывают в стандартный вывод, не должны знать или заботиться о том, что они могут взаимодействовать с другим процессом. Если хотите знать, каноническим способом проверки этого является попытка выполнить с дескриптором '

lseek(fd, 0L, SEEK_CUR)
'; этот вызов пытается отсчитать 0 байтов от текущего положения, т е. операция, которая ничего не делает [94] . Эта операция завершается неудачей для каналов и не наносит никакого вреда другим файлам.

94

Такая операция часто обозначается no-op — «no operation» (нет операции) — Примеч. автора.

Поделиться:
Популярные книги

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11

Бастард Императора. Том 12

Орлов Андрей Юрьевич
12. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 12

Новик

Ланцов Михаил Алексеевич
2. Помещик
Фантастика:
альтернативная история
6.67
рейтинг книги
Новик

Неправильный лекарь. Том 1

Измайлов Сергей
1. Неправильный лекарь
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Неправильный лекарь. Том 1

Законы Рода. Том 3

Андрей Мельник
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Роза ветров

Кас Маркус
6. Артефактор
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Роза ветров

Апокриф

Вайс Александр
10. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Апокриф

Чужак из ниоткуда 3

Евтушенко Алексей Анатольевич
3. Чужак из ниоткуда
Фантастика:
космическая фантастика
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 3

Вперед в прошлое 8

Ратманов Денис
8. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 8

Слэпшот

Хоуп Ава
Невозможно устоять. Горячие романы Авы Хоуп
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Слэпшот

Ярар. Начало

Грехов Тимофей
1. Ярар
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ярар. Начало

Японская война 1904. Книга третья

Емельянов Антон Дмитриевич
3. Второй Сибирский
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Японская война 1904. Книга третья

Я уже граф. Книга VII

Дрейк Сириус
7. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже граф. Книга VII

Наследник жаждет титул

Тарс Элиан
4. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник жаждет титул