Средства межпроцессорного взаимодействия, страница 5

1) Для случая input.txt

$ gcc -o pipe pipe.c

$./pipe input.txt

PPipe.c: father

Pipe.c: son

Pipe.c: file [input.txt] is open

Pipe.c: write data [kekeke] to pipe

Pipe.c: read from pipe kekekE├┐├┐├┐T├и├┐├┐├┐

Видно, что pipe хранит и символы перевода строк и пробелы, представляя это в случайном ASCII коде. (надо заметить, в MWord 2003 символы выглядят по-другому, в оригинальном варианте – строгая последовательность, по два на перевод строки и один на пробел). Однако вся информация без существенных искажений была записана и считана из однонаправленного pipe-канала.

2) Для случая input.2

# ./pipe input.2

Pipe.c: father

Pipe.c: son

Pipe.c: file [input.2] is open

Pipe.c: write data [WOW!] to pipe

Pipe.c: read from pipe WOW!

В данном примере входной файл состоит из одной строчки, которая в чистом виде перекочевала и в канал обмена.

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


6.  Именованные каналы

Теперь рассмотрим работу с FIFO. Для этой цели были разработаны 2 программы – server.c, которая создает два именованных канала (на запись и чтение) и переходит в режим сервера, который записывает имя файла в канал 1 (для записи) и читает данные из канала 2 в зарезервированный буфер. И программа client.c, в основной части которой происходит открытие созданных каналов на чтение и запись (в противоположном порядке), переход в клиентскую часть и, после ее выполнения, удаления созданных каналов системным вызовом unlink. В клиентской части происходит чтение имени файла из канала 1 и запись данных из файла в канал 2.

#ifndef _head_er_h_

#define _head_er_h_

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

void client(int,int);

void server(int,int);

struct i_info {

            char *name_server;                        //имя файла server.c (возвращается argv[0])

            char *name_client;             //имя файла client.c (возвращается argv[0])

            char *chan_read;                //имя файла канала на чтение

            char *chan_write;                //имя файла канала на запись

            char *FName;                      //имя файла (задается как argv[1] в сервере)

            char *add_file;                     //имя файла (задается как argv[1] в клиенте)

            int flag;                                  //флаг для обработки сигналов

            int fdw;                                  //дескриптор файла на запись в клиенте

} obj;

void erase(char *temp) {                //процедура очистки любого буфера

            int k = 0;

            while(temp[k]) {

                        temp[k] = NULL;

                        k++;

            };

            return;

};

#endif

Листинг 6.1. Заголовочный файл header.h

Он включает подключаемые библиотеки, прототипы функций, структуру хранения необходимой информации и процедуру очистки какого-либо буфера обмена.

Рассмотрим основные программы:

Рис. 6.1. Схема программы server.c

Рис. 6.2. Схема программы client.c