Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР5.docx
Скачиваний:
15
Добавлен:
12.02.2016
Размер:
400.53 Кб
Скачать

Механізми взаємодії між процесами в ос Unix

При вирішенні задачі синхронізації процесів та їх взаємодії за допомогою різних механізмів, що надаються ОС, може знадобитися використання наступних системних викликів

  • створення, завершення процесу, отримання інформації про процес: fork, exit, getpid, getppid і т. д .;

  • синхронізація процесів: signal, kill, sleep, alarm, wait, pause, semop, semctl, semcreate і т. д .;

  • створення інформаційного каналу, розділяється пам'яті, черги повідомлень і робота з ними: pipe, mkfifo, read, write, msgget, shmget, msgctl, shmctl і т. д.

Механізм взаємодії між процесами (Inter-Process Communication Facilities - IPC) включає

  • засоби, що забезпечують можливість синхронізації процесів при доступі до спільно використовуваних ресурсів - семафори (semaphores);

  • засоби, що забезпечують можливість посилки процесом безпідставного процесу - черги повідомлень (Message queries);

  • засоби, що забезпечують можливість наявності загальної для процесів пам'яті - сегменти розділеної пам'яті (shared memory segments);

  • засоби, що забезпечують можливість «спілкування» процесів, як споріднених, так і ні, через пайпи або канали (pipes).

Найбільш загальним поняттям IPC є ключ, що зберігається в загальносистемній таблиці і означає об'єкт міжпроцесорної взаємодії, доступний декільком процесам. Позначений ключем об'єкт може бути чергою повідомлень, набором семафорів або сегментом розділеної пам'яті. Ключ має тип keyt, склад якого залежить від реалізації і визначається у файлі <sys / types.h>. Ключ використовується для створення об'єкта між процесами взаємодії або отримання доступу до існуючого об'єкта

Іменовані і неіменовані канали (пайпи)

Операційні системи сімейства Unix завжди підтримують два типи одно направлених каналів

• неіменовані канали;

• іменовані канали FIFO.

Неіменовані канали - це найперша форма IPC в Unix (1973), головним недоліком яких є відсутність імені, внаслідок чого вони можуть використовуватися для взаємодії тільки спорідненими процесами. В Unix System третьої редакції (1982) були додані канали FIFO, які називаються іменованими каналами. Абревіатура FIFO розшифровується як «first in, first out» - «першим увійшов, першим вийшов», тобто ці канали працюють як черги. Іменовані канали в Unix функціонують подібно неіменованого - дозволяють передавати дані тільки в одну сторону. Однак на відміну від програмних каналів кожному каналу FIFO зіставляється повне ім'я в файлової системі, що дозволяє двом неспорідненим процесам звернутися до одного і того ж FIFO. Доступ і до іменованих каналах, і до неіменованих організовується за допомогою звичайних функцій read і write.

FIFO створюється викликом mkfifo

#include <sys / types.h> #include <sys / stat.h>

int mkfifo (const char * pathname, mode_t mode);

/ * Повертає 0 при успішному виконанні, -1 при помилці * /

Тут pathname - звичайне для Unix повне ім'я файлу, яке і буде ім'ям FIFO.

Аргумент mode вказує бітову маску дозволів доступу до файлу (табл. 4.2), аналогічно другому аргументу команди open.

Функція mkfifo діє як open, викликана з аргументом mode = O_CREAT | O_EXCL. Це означає, що створюється новий канал FIFO або повертається помилка EEXIST у випадку, якщо канал із заданим повним ім'ям вже існує. Якщо не потрібно створювати новий канал, викликайте open замість mkfifо. Для відкриття існуючого каналу або створення нового, в тому випадку, якщо його ще не існує, викличте mkfifo, перевірте, чи не повернута помилка EEXIST, і якщо таке трапиться, викличте функцію open.

Команда mkfifo також створює канал FIFO. Нею можна користуватися в сценаріях інтерпретатора або з командного рядка.

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

Після створення канал FIFO повинен бути відкритий на читання або запис за допомогою якої функції open, або однієї зі стандартних функцій відкриття файлів з бібліотеки вводу-виводу (наприклад, fopen). FIFO може бути відкритий або тільки на читання, або тільки на запис. Не можна відкривати канал на читання і запис, оскільки іменовані канали можуть бути тільки односторонніми.

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

Неіменовані канали створюються викликом pipe () і надають можливість тільки односпрямованої (односторонньої) передачі даних:

#include <unistd.h>

int fd [2];

pipe (fd);

/ * Повертає 0 у випадку успішного завершення, -1 - у разі помилки; * /

Функція повертає два файлових дескриптора: fd [0] і fd [l], причому перший відкритий для читання, а другий - для запису.

Хоча канал створюється одним процесом, він рідко використовується тільки цим процесом, канали зазвичай використовуються для зв'язку між двома процесами (батьківським і дочірнім) наступним чином: процес створює канал, а потім викликає fork, створюючи свою копію - дочірній процес; потім батьківський процес закриває відкритий для читання кінець каналу, а дочірній - відкритий на запис кінець каналу. Це забезпечує односторонню передачу даних між процесами .

Рис.2. Функціонування каналу для випадку одиночного процесу

Рис.3. Функціонування каналу після створення дочірнього процесу (після виклику fork)

Рис.4. Функціонування каналу між двома процесами

Рис.5. Функціонування каналів між трьома процесами в конвеєрній обробці

При вводі команда типу:

who| sort| 1р

інтерпретатор команд Unix виконує вищеописані дії для створення трьох процесів з двома каналами між ними (рис. 5).

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

Усі розглянуті вище неіменовані канали були односпрямованим (односторонніми), тобто дозволяли передавати дані тільки в одну сторону. При необхідності передачі даних в обидві сторони потрібно створювати пару каналів і використовувати кожен з них для передачі даних в одну сторону. Етапи створення двонаправленого неіменованого каналу IPC є наступними:

  • створюються канали 1 (fd1 [0] і fd1 [1]) і 2 (fd2 [0] і fd2 [0]);

  • виклик fork;

  • батьківський процес закриває доступний для читання кінець каналу 1 (fd1 [0]);

  • батьківський процес закриває доступний для запису кінець каналу 2 (fd2 [1]);

  • дочірній процес закриває доступний для запису кінець каналу 1 (fd1 [1]);

  • дочірній процес закриває доступний для читання кінець каналу 2 (fd2 [0]).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]