working lab4 mine
This commit is contained in:
238
lab_4/README_lab4.md
Normal file
238
lab_4/README_lab4.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# Лабораторная работа №4: Каналы передачи данных
|
||||
|
||||
## Цель работы
|
||||
Получить навыки организации обмена информацией между процессами средствами неименованных или именованных каналов в программах на языке C в операционных системах семейства Linux.
|
||||
|
||||
## Описание задания
|
||||
|
||||
Лабораторная работа является модификацией лабораторной работы №3, в которой обмен данными между родительской и дочерними программами производится через программные каналы.
|
||||
|
||||
### Вариант 12
|
||||
Программа читает текстовый файл построчно. Для каждой строки первый символ становится ключом, и все вхождения этого символа в строке заменяются пробелами, пока не будет достигнуто максимальное количество замен.
|
||||
|
||||
## Реализованные решения
|
||||
|
||||
### 1. Решение с неименованными каналами (pipes)
|
||||
|
||||
**Файлы:**
|
||||
- `parent_pipe.c` - родительская программа
|
||||
- `child_pipe.c` - дочерняя программа
|
||||
|
||||
**Принцип работы:**
|
||||
1. Родительский процесс создает три канала для каждого дочернего процесса:
|
||||
- `pipe_to_child` - для передачи данных дочернему процессу
|
||||
- `pipe_from_child` - для получения обработанных данных
|
||||
- `pipe_error` - для получения количества замен
|
||||
|
||||
2. Родительский процесс:
|
||||
- Читает данные из входного файла
|
||||
- Передает данные дочернему процессу через `pipe_to_child`
|
||||
- Получает обработанные данные через `pipe_from_child`
|
||||
- Записывает результат в выходной файл
|
||||
|
||||
3. Дочерний процесс:
|
||||
- Перенаправляет stdin на чтение из канала (dup2)
|
||||
- Перенаправляет stdout на запись в канал (dup2)
|
||||
- Обрабатывает данные согласно варианту 12
|
||||
- Возвращает количество замен через stderr
|
||||
|
||||
**Преимущества:**
|
||||
- Простая реализация для родственных процессов
|
||||
- Автоматическая синхронизация через блокирующие операции чтения/записи
|
||||
- Нет необходимости в файловых дескрипторах на диске
|
||||
|
||||
**Недостатки:**
|
||||
- Работает только между родственными процессами
|
||||
- Ограниченный размер буфера канала
|
||||
|
||||
### 2. Решение с именованными каналами (FIFO)
|
||||
|
||||
**Файлы:**
|
||||
- `fifo_server.c` - серверная программа
|
||||
- `fifo_client.c` - клиентская программа
|
||||
|
||||
**Принцип работы:**
|
||||
1. Сервер создает два именованных канала:
|
||||
- `/tmp/fifo_request` - для получения запросов
|
||||
- `/tmp/fifo_response` - для отправки ответов
|
||||
|
||||
2. Клиент:
|
||||
- Читает данные из входного файла
|
||||
- Отправляет данные серверу через `fifo_request`
|
||||
- Получает обработанные данные через `fifo_response`
|
||||
- Записывает результат в выходной файл
|
||||
|
||||
3. Сервер:
|
||||
- Ожидает запросы от клиентов
|
||||
- Обрабатывает данные согласно варианту 12
|
||||
- Отправляет результат обратно клиенту
|
||||
|
||||
**Преимущества:**
|
||||
- Работает между неродственными процессами
|
||||
- Клиент-серверная архитектура
|
||||
- Возможность обработки запросов от нескольких клиентов
|
||||
|
||||
**Недостатки:**
|
||||
- Более сложная реализация
|
||||
- Требуется управление файлами в файловой системе
|
||||
- Необходима синхронизация между клиентом и сервером
|
||||
|
||||
## Компиляция и запуск
|
||||
|
||||
### Компиляция всех программ
|
||||
```bash
|
||||
make -f Makefile_lab4 all
|
||||
```
|
||||
|
||||
### Тестирование с неименованными каналами
|
||||
```bash
|
||||
make -f Makefile_lab4 test_pipes
|
||||
```
|
||||
|
||||
### Тестирование с именованными каналами
|
||||
|
||||
**Вариант 1: Автоматический тест**
|
||||
```bash
|
||||
make -f Makefile_lab4 test_fifo_auto
|
||||
```
|
||||
|
||||
**Вариант 2: Ручной запуск в двух терминалах**
|
||||
|
||||
Терминал 1 (сервер):
|
||||
```bash
|
||||
make -f Makefile_lab4 test_fifo_server
|
||||
```
|
||||
|
||||
Терминал 2 (клиент):
|
||||
```bash
|
||||
make -f Makefile_lab4 test_fifo_client
|
||||
```
|
||||
|
||||
### Сравнение с оригинальной версией
|
||||
```bash
|
||||
make -f Makefile_lab4 test_compare
|
||||
```
|
||||
|
||||
### Запуск всех тестов
|
||||
```bash
|
||||
make -f Makefile_lab4 test_all
|
||||
```
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Неименованные каналы
|
||||
```bash
|
||||
./parent_pipe ./child_pipe 10 input1.txt output1.txt input2.txt output2.txt
|
||||
```
|
||||
|
||||
### Именованные каналы
|
||||
|
||||
Запустить сервер:
|
||||
```bash
|
||||
./fifo_server 10
|
||||
```
|
||||
|
||||
В другом терминале запустить клиент:
|
||||
```bash
|
||||
./fifo_client input1.txt output1.txt
|
||||
./fifo_client input2.txt output2.txt
|
||||
```
|
||||
|
||||
## Обработка исключительных ситуаций
|
||||
|
||||
Программы предусматривают обработку следующих ошибок:
|
||||
- Отсутствие или неверное количество входных параметров
|
||||
- Ошибки открытия входного и/или выходного файла
|
||||
- Ошибки создания каналов
|
||||
- Ошибки создания дочерних процессов
|
||||
- Ошибки чтения и записи через каналы
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Используемые системные вызовы
|
||||
|
||||
**Неименованные каналы:**
|
||||
- `pipe()` - создание канала
|
||||
- `fork()` - создание дочернего процесса
|
||||
- `dup2()` - дублирование файлового дескриптора
|
||||
- `read()` / `write()` - чтение/запись данных
|
||||
- `close()` - закрытие файлового дескриптора
|
||||
- `waitpid()` - ожидание завершения дочернего процесса
|
||||
- `execl()` - запуск новой программы
|
||||
|
||||
**Именованные каналы:**
|
||||
- `mkfifo()` - создание именованного канала
|
||||
- `open()` - открытие FIFO
|
||||
- `read()` / `write()` - чтение/запись данных
|
||||
- `close()` - закрытие FIFO
|
||||
- `unlink()` - удаление FIFO
|
||||
|
||||
### Схема работы каналов
|
||||
|
||||
**Неименованные каналы (pipes):**
|
||||
```
|
||||
Родительский процесс Дочерний процесс
|
||||
[файл] → read stdin ← pipe
|
||||
↓ ↓
|
||||
pipe → write read → process
|
||||
↓
|
||||
read ← pipe write → stdout
|
||||
↓
|
||||
write → [файл]
|
||||
```
|
||||
|
||||
**Именованные каналы (FIFO):**
|
||||
```
|
||||
Клиент Сервер
|
||||
[файл] → read /tmp/fifo_request ← open
|
||||
↓ ↓
|
||||
write → /tmp/fifo_request read → process
|
||||
↓
|
||||
read ← /tmp/fifo_response write → /tmp/fifo_response
|
||||
↓
|
||||
write → [файл]
|
||||
```
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
lab4/
|
||||
├── parent_pipe.c # Родительская программа (pipes)
|
||||
├── child_pipe.c # Дочерняя программа (pipes)
|
||||
├── fifo_server.c # Серверная программа (FIFO)
|
||||
├── fifo_client.c # Клиентская программа (FIFO)
|
||||
├── parent.c # Оригинальная версия (Lab 3)
|
||||
├── lab1_var12.c # Оригинальная версия (Lab 1)
|
||||
├── Makefile_lab4 # Makefile для компиляции и тестирования
|
||||
└── README_lab4.md # Документация
|
||||
```
|
||||
|
||||
## Контрольные вопросы (стр. 82)
|
||||
|
||||
1. **Что такое канал (pipe)?**
|
||||
- Канал - это механизм межпроцессного взаимодействия (IPC), представляющий собой однонаправленный канал связи между процессами.
|
||||
|
||||
2. **В чем разница между именованными и неименованными каналами?**
|
||||
- Неименованные каналы существуют только в памяти и доступны только родственным процессам
|
||||
- Именованные каналы (FIFO) создаются в файловой системе и доступны любым процессам
|
||||
|
||||
3. **Как создать канал?**
|
||||
- Неименованный: `int pipe(int fd[2])`
|
||||
- Именованный: `int mkfifo(const char *pathname, mode_t mode)`
|
||||
|
||||
4. **Что происходит при чтении из пустого канала?**
|
||||
- Процесс блокируется до тех пор, пока в канал не будут записаны данные
|
||||
|
||||
5. **Что происходит при записи в заполненный канал?**
|
||||
- Процесс блокируется до тех пор, пока в канале не освободится место
|
||||
|
||||
6. **Как передать данные через канал?**
|
||||
- Используя системные вызовы `write()` для записи и `read()` для чтения
|
||||
|
||||
7. **Зачем нужно закрывать неиспользуемые концы канала?**
|
||||
- Для корректного определения EOF при чтении
|
||||
- Для освобождения ресурсов
|
||||
- Для предотвращения deadlock
|
||||
|
||||
## Автор
|
||||
Лабораторная работа выполнена в рамках курса "Системное программирование в среде Linux"
|
||||
Reference in New Issue
Block a user