Некоторые программы формируют в отображаемом файле структуры данных. При каждом следующем запуске программа повторно инициализирует файл в памяти, вследствие чего восстанавливается начальное состояние структур. В подобной ситуации следует помнить о том, что указатели на структуры будут некорректными, если они не локализованы в пределах одной отображаемой области и если файл не загружается по одному и тому же адресу.
Другой удобный прием — отображение в памяти файла /dev/zero
5.4. Каналы
В интерпретаторе команд канал создается оператором |
ls
, а второй — для программы less
:% ls | less
Интерпретатор также формирует канал, соединяющий стандартный выходной поток подпроцесса ls
less
. Таким образом, имена файлов, перечисляемые программой ls
, посылаются программе постраничной разбивки less
в том порядке, в котором они отображались бы нетерминале.Информационная емкость канала ограничена. Если пишущий процесс помещает данные в канал быстрее, чем читающий процесс их извлекает, и буфер канала переполняется, то пишущий процесс блокируется до тех пор, пока буфер не освободится. И наоборот: если читающий процесс обращается к каналу, в который еще не успели поступить данные, он блокируется в ожидании данных. Таким образом, канал автоматически синхронизирует оба процесса.
5.4.1. Создание каналов
Канал создается с помощью функции pipe()
int pipe_fds[2];
int read_fd;
int write_fd;
pipe(pipe_fds);
read_fd = pipe_fds[0];
write_fd = pipe_fds[1];
Данные, записываемые в файл write_fd
read_fd
.5.4.2. Взаимодействие родительского и дочернего процессов
Функция pipe()
fork()
.В программе, показанной в листинге 5.7. родительский процесс записывает в канал строку, а дочерний процесс читает ее. С помощью функции fdopen()
FILE*
. Благодаря этому появляется возможность использовать высокоуровневые функции ввода-вывода, такие как printf()
и fgets()
.#include
#include
#include
/* Запись указанного числа копий (COUNT) сообщения (MESSAGE)
в поток (STREAM) с паузой между каждой операцией. */
void writer(const char* message, int count, FILE* stream) {
for (; count > 0; --count) {
/* Запись сообщения в поток с немедленным "выталкиванием"
из буфера. */
fprintf(stream, "%s\n", message);
fflush(stream);
/* Небольшая пауза. */
sleep(1);
}
/* Чтение строк из потока, пока он не опустеет. */
void reader(FILE* stream) {
char buffer[1024];
/* Чтение данных, пока не будет обнаружен конец потока.
Функция fgets() завершается, когда встречает символ
новой строки или признак конца файла. */
while (!feof(stream)
&& !ferror(stream)