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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

Атрибуты, которые порожденный процесс наследует от родителя, устанавливаются в те же значения, которые были в родительском процессе в момент выполнения

fork
. Однако, с этого момента два процесса продолжают идти собственными путями (большей частью) независимо один от другого. Например, если порожденный процесс изменяет каталог, каталог родительского процесса не затрагивается. Сходным образом, если порожденный изменяет среду, среда родителя не меняется.

Открытые файлы являются важным исключением из этого правила. Дескрипторы открытых файлов являются разделяемыми,

и действия одного процесса с разделяемым дескриптором файла затрагивает состояние файла также и для другого процесса. Это лучше всего понять, изучив рис. 9.1.

Рис. 9.1. Разделение дескрипторов файлов

Рисунок отображает внутренние структуры данных ядра. Ключевой структурой данных является таблица файлов. Каждый элемент ссылается на открытый файл. Помимо других учетных данных, таблица файлов содержит текущее положение (смещение чтения/записи) в файле. Оно устанавливается либо автоматически каждый раз при чтении или записи файла, либо непосредственно через

lseek
(см. раздел 4.5 «Произвольный доступ: перемещения внутри файла»).

Дескриптор файла, возвращенный функциями

open
или
creat
, действует как индекс имеющегося в каждом процессе массива указателей на таблицу файлов. Размер этого массива не превышает значение, возвращенное
getdtablesize
(см. раздел 4.4.1 «Понятие о дескрипторах файлов»).

На рис. 9.1 показаны два процесса, разделяющие стандартный ввод и стандартный вывод; для каждого из процессов указаны одни и те же элементы в таблице файлов. Поэтому, когда процесс 45 (порожденный) осуществляет

read
, общее смещение обновляется; следующий раз, когда процесс 42 (родитель) осуществляет
read
, он начинает с позиции, в которой закончила чтение
read
процесса 45.

Это легко можно видеть на уровне оболочки:

$ cat data /* Показать содержание демонстрационного файла */

line 1

line 2

line 3

line 4

$ ls -l test1 ; cat test1 /* Режим и содержание тестовой программы */

– rwxr-xr-x 1 arnold devel 93 Oct 20 22:11 test1

#! /bin/sh

read line ; echo p: $line /* Прочесть строку в родительской оболочке,

вывести ее */

( read line ; echo с: $line ) /* Прочесть строку в порожденной оболочке,

вывести ее */

read line ; echo p: $line /* Прочесть строку в родительской оболочке,

вывести ее */

$ test1 < data /* Запустить программу */

p: line 1 /* Родитель начинает сначала */

c: line 2 /* Порожденный продолжает
оттуда, где остановился родитель */

p: line 3 /* Родитель продолжает оттуда, где остановился порожденный */

Первая исполняемая строка

test1
читает из стандартного ввода строку, изменяя смещение файла. Следующая строка
test1
запускает команды, заключенные между скобками, в подоболочке (subshell). Это отдельный процесс оболочки, созданный — как вы догадались — с помощью
fork
. Порожденная подоболочка наследует от родителя стандартный ввод, включая текущее смещение. Этот процесс читает строку и обновляет разделяемое смещение в файле. Когда третья строка, снова в родительской оболочке, читает файл, она начинает там, где остановился порожденный.

Хотя команда

read
встроена в оболочку, все работает таким же образом и для внешних команд. В некоторых ранних Unix-системах была команда
line
, которая читала одну строку ввода (по одному символу за раз!) для использования в сценариях оболочки; если бы смещение файла не было разделяемым, было бы невозможно использовать такую команду в цикле.

Разделение дескрипторов файлов и наследование играют центральную роль в перенаправлении ввода/вывода оболочки; системные вызовы и их семантика делают примитивы уровня оболочки простыми для реализации на С, как мы позже увидим в данной главе.

9.1.1.3. Разделение дескрипторов файлов и

close

Тот факт, что несколько дескрипторов файлов могут указывать на один и тот же открытый файл, имеет важное следствие: файл не закрывается до тех пор, пока не будут закрыты все дескрипторы файла.

Позже в главе мы увидим, что несколько дескрипторов для одного файла могут существовать не только для разных процессов, но даже и внутри одного и того же процесса; это правило особенно важно для работы с каналами (pipes).

Если вам нужно узнать, открыты ли два дескриптора для одного и того же файла, можете использовать

fstat
(см. раздел 5.4.2 «Получение сведений о файле») для двух дескрипторов с двумя различными структурами
struct stat
. Если соответствующие поля
st_dev
и
st_ino
равны, это один и тот же файл.

Позже в главе мы завершим обсуждение манипуляций с дескрипторами файлов и таблицей дескрипторов файлов.

9.1.2. Идентификация процесса:

getpid
и
getppid

У каждого процесса есть уникальный ID номер процесса (PID). Два системных вызова предоставляют текущий PID и PID родительского процесса:

#include <sys/types.h> /* POSIX */

#include <unistd.h>

pid_t getpid(void);

pid_t getppid(void);

Функции так просты, как выглядят:

pid_t getpid(void) 
Возвращает PID текущего процесса

pid_t getppid(void)
Возвращает PID родителя.

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

Бастард

Осадчук Алексей Витальевич
1. Последняя жизнь
Фантастика:
фэнтези
героическая фантастика
попаданцы
5.86
рейтинг книги
Бастард

Старый, но крепкий 8

Крынов Макс
8. Культивация без насилия
Фантастика:
рпг
уся
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Старый, но крепкий 8

Законник Российской Империи. Том 2

Ткачев Андрей Юрьевич
2. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
6.40
рейтинг книги
Законник Российской Империи. Том 2

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Локки 6. Потомок бога

Решетов Евгений Валерьевич
6. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Локки 6. Потомок бога

Студиозус 2

Шмаков Алексей Семенович
4. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус 2

Мастер порталов

Лисина Александра
8. Гибрид
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер порталов

Тринадцатый III

NikL
3. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый III

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Девять драконов

Скотт Джастин
Детективы:
триллеры
5.00
рейтинг книги
Девять драконов

Последний Паладин. Том 14

Саваровский Роман
14. Путь Паладина
Фантастика:
аниме
фэнтези
попаданцы
5.75
рейтинг книги
Последний Паладин. Том 14

Справочник логопеда

Коллектив авторов
Научно-образовательная:
медицина
6.25
рейтинг книги
Справочник логопеда

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой