Лабораторна робота №9. Використання каналів



Мета:Оволодіння технологією використання каналів ОС UNIX. Застосування отриманих знань для написання програм керування файлами.

 

Завдання для самостійної підготовки:

Вивчити:

− способи межпроцессного взаємодії ОС UNIX;

− організацію каналів ОС UNIX;

− системні виклики керування каналами;

 

Методичні вказівки

Заганьні відомості

Система Linux IPC (Inter-process communication) надає кошти для взаємодії процесів між собою.

У розпорядженні програмістів є кілька методів IPC:

− напівдуплексні канали UNIX,

− FIFO (іменовані канали),

− черги повідомлень,

− безлічі семафорів,

− поділювані сегменти пам'яті,

− мережні сокети,

− полнодуплексні канали

    

Використання каналів

 

Канал - це засіб зв'язку стандартного висновку одного процесу зі стандартним уведенням іншого. Канали - це найстарший з інструментів IPC, що існує приблизно із часу появи самих ранніх версій оперативної системи UNIX. Вони надають метод однобічних комунікацій (звідси термін half-duplex) між процесами.

Коли процес створює канал, ядро встановлює два файлових дескриптори для користування цим каналом. Один такий дескриптор використовується, щоб відкрити шлях уведення в канал (запис), у той час як іншої застосовується для одержання даних з каналу (читання). Якщо процес посилає дані через канал (fd0), він має можливість одержати цю інформацію з fd1. процес, що створює канал, звичайно породжує дочірній процес. Як тільки дочірній процес успадкує який-небудь відкритий файловий дескриптор від батька, ми одержуємо базу для мультипроцессовой комунікації (між батьком і нащадком). Конструкція каналу виглядає в такий спосіб

 

                  in <-----                 in

Parent Process             Kernel                    Child Process

                      out                   <----- out

 

Рисунок 4 – Конструкція каналу

 

Створення каналів виконується з використанням функції

#include <unistd.h> int pipe(int *filedes);

 

Функція повертає два дескриптори:

filedes[0] - для запису;

filedes[1] - для читання.

 

Обмін інформацією виконується з використання функцій запису й читання API. Канали використовуються для родинних процесів.

Незалежні процеси можуть використовувати іменовані канали. Такі канали створюються функцією.

 

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/fcntl.h>

#include <unistd.h>

int mknod(const char *pathname, mode_t, dev_t dev);

 

Перший параметр специфицирует ім'я створюваного каналу, параметр mode задає права доступу й тип (для іменованого каналу використовується значення S_IFIFO). Третій параметр ігнорується. Функція повертає ознаку нормального завершення - 0, при помилці вертається значення -1.

Знищення каналу виконується по функції

int unlink(const char *pathname)

 

Наступний приклад ілюструє передачу короткого повідомлення між родительски й дочірнім процесом.

 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <sys/types.h>

int main() {

pid_t childPid;

int flds[2], status;

char buf[]="Message";

// Створення каналу

if (pipe(flds) == -1)

{ perror("Pipe"); exit(1); }

// Розгалуження процесів

switch (childPid=fork())

{ case -1: perror("fork");

          exit(2);

case 0:

close(flds[0]);

//Нащадок

printf("Child process %d\n", getpid()); write(flds[1], buf,

strlen(buf));

close(flds[1]); exit(0); }

// Процес - батько

printf("Process %d\n", getpid());

close(flds[1]);

read(flds[0], buf, 80);

printf("String -> %s\n", buf);

close(flds[0]);

wait(&status);

return status;

}

 

На початку програми створюється канал і формуються два ідентифікатори файлів для цього каналу (flds[0] і flds[1]). Будемо вважати, що в батьківського процесу flds[0] використовується для прийому даних, тому на початку секції батьківського процесу необхідно закрити канал, пов'язаний з файловим ідентифікатором flds[1]. У породженому процесі закривається канал з ідентифікатором flds[0].

Наступний приклад ілюструє обмін даними між двома незалежними процесами через іменований канал.

Перша програма служить сервером, вона створює іменований канал по функції

mkfifo(NAME, S_IFIFO|S_IRWXU|S_IRWXG|S_IRWXO).

Як перший параметр використовується рядок, певна константою NAME. Другий параметр являє собою комбінацію ключів, що визначають дозвіл повних прав доступу для всіх категорій користувачів. Після створення каналу на стороні сервера він відкривається в режимі читання. Після приходу повідомлення, текст цього повідомлення виводиться на екран і канал закривається. Наприкінці програми функцією unlink(NAME) канал знищується. Відкриття й знищення каналу виконуються з використанням того самого ім'я (константа NAME зі значенням "sfifo.cc").

 

/* Сервер. Створює FIFO і очікує повідомлення */

#include <iostream.h>

#include <stdio.h>

#include <errno.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#define NAME "sfifo.cc"

int main() {

int fd;

char buf[80];

unlink(NAME);

if(mkfifo(NAME, S_IFIFO|S_IRWXU|S_IRWXG|S_IRWXO)) {

 perror("Помилка FIFO");

return 1; }

if((fd=open(NAME, O_RDONLY))==-1) {

perror("Помилка відкриття файлу сервера"); }

read(fd, buf, sizeof(buf));

cout<<"Отримано->"<<buf<<endl; close(fd);

unlink(NAME);

return 0;

}

Програма - клієнт виводить на екран текст запиту на уведення повідомлення й після уведення рядка відкриває канал на запис. Після передачі вмісту буфера в канал, останній закривається.

 

/* Клієнт */

#include <iostream.h>

#include <stdio.h>

#include <errno.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <string.h>

#include <sys/stat.h>

#define NAME "sfifo.cc"

int main() {

char text[80];

int fd;

cout<<"Увести ссобщение"<<endl;

cin>>text;

if((fd=open(NAME, O_WRONLY))==-1) {

perror("Помилка відкриття клієнта");

return 1; }

write(fd, text, strlen(text)); close(fd); return 0;

}

Індівідуальні завдання

Написати дві програми, які створюють між собою канал. Одна програма відіграє роль клієнта, друга служить сервером. Функції клієнта й сервера визначаються варіантами завдань на виконання лабораторної роботи. У парних варіантах завдання використовувати іменовані канали.

Варіанти завдань

1. Клієнт передає серверу через канал запит у вигляді повного шляху до файлу. Сервер читає цей файл і передає клієнтові його вміст або повідомлення про помилку, якщо файл із зазначеним ім'ям не існує або не доступний для читання. Клієнт виводить прийняті дані на термінал.

2. Клієнт і сервер обмінюються повідомленнями, що вводяться із клавіатури. Програми запускаються на різних терміналах. Прийняті повідомлення виводяться на екран.

3. Сервер виконує команду ps, і результати її виконання передаються клієнтові, що виводить їх на термінал.

4. Клієнт і сервер обмінюються між собою повідомленнями. Програми запускаються на різних терміналах. Кожна програма записує прийняті повідомлення у файл, розширення якого є значенням ідентифікатора процесу, що відповідає даній програмі.

5. Клієнт передає серверу запит у вигляді повного шляху до файлу. Сервер читає цей файл і передає клієнтові його вміст або повідомлення про помилку, якщо файл не існує або не доступний для читання. Клієнт записує отриману інформацію у файл у поточному каталозі з тим же ім'ям і доповнює його розширенням result.

6. Клієнт приймає із клавіатури команди й передає їхньому серверу. Сервер виконує прийняті команди й повертає результати їхнього виконання клієнтові. Прийняті дані клієнт виводить на термінал. Програми запускати на різних терміналах.

7. Клієнт приймає із клавіатури команди й передає їхньому серверу. Сервер виконує ці команди, результати вертаються клієнтові, що записує їх у файл.

8. Клієнт запитує в сервера кількість файлів, що перебувають у зазначеному каталозі. Отриманий результат виводиться клієнтом на термінал.

9. Клієнт формує запит, що містить ім'я файлу. Сервер визначає, чи є зазначений файл каталогом і формує відповідну відповідь. Відповідь виводиться клієнтом на екран.

10. Клієнт формує запит, що містить ім'я каталогу. Сервер переглядає каталог і передає клієнтові кількість підкаталогів, що мають у даному каталозі. Клієнт виводить отриману інформацію на екран.

11. Клієнт формує запит, що містить ім'я каталогу. Сервер перевіряє, чи є дозвіл запису в цей каталог, при необхідності встановлює це право й інформує клієнта про результати виконання операції. Клієнт виводить на екран отримане від сервера повідомлення.

12. Клієнт запитує в сервера кількість працюючих у цей момент часу користувачів. Якщо кількість користувачів більше заданого числа на термінал виводиться повідомлення.


Дата добавления: 2018-04-05; просмотров: 439; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!