Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лекции_укр.doc
Скачиваний:
6
Добавлен:
22.04.2019
Размер:
697.34 Кб
Скачать

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

Для створення каналу служить функція pipe. Вона використовується для відкриття каналу й на читання й на запис. Звичайно процес створює канал до створення породжених процесів, з якими він буде взаємодіяти через канал. Канал може використовуватися для взаємодії як між батьківським і породженим процесами, так і між двома рівноправними процесами.

Функція pipe визначена в заголовному файлі <unistd.h>:

int pipe(int FILEDES[2])

Функція створює потік і поміщає дескриптори файлів для читання з потоку й запису в потік відповідно в FILEDES[0] і FILEDES[1]. У випадку успішного виконання функція повертає значення 0, при виникненні помилки вертається -1, у змінна errno може приймати наступні значення:

EMFILE процес має занадто багато відкритих файлів;

ENFILE система має занадто багато відкритих файлів. В Linux ця помилка ніколи не виникає.

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

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

void read_from_pipe (int file)

{

FILE *stream;

int c;

stream = fdopen (file, "r");

while ((c = fgetc (stream)) != EOF)

putchar (c);

fclose (stream);

}

void write_to_pipe (int file)

{

FILE *stream;

stream = fdopen (file, "w");

fprintf (stream, "hello, world!\n");

fprintf (stream, "goodbye, world!\n");

fclose (stream);

}

Int main (void)

{

pid_t pid;

int mypipe[2];

if (pipe (mypipe))

{

fprintf (stderr, "Pipe failed.\n");

return EXIT_FAILURE;

}

pid = fork ();

if (pid == (pid_t) 0)

{

read_from_pipe (mypipe[0]);

return EXIT_SUCCESS;

}

else if (pid < (pid_t) 0)

{

fprintf (stderr, "Fork failed.\n");

return EXIT_FAILURE;

}

else

{

write_to_pipe (mypipe[1]);

return EXIT_SUCCESS;

}

}

3.7.3 Створення fifo-Файлів

FIFO-Файли схожі з каналами, однак створюються іншим способом. FIFO- файли створюються у файловій системі за допомогою функції mkfifo. Після створення такого файлу, будь-який процес може відкрити його для читання й запису таким же способом, як і звичайний файл. Проте, він повинен бути відкритий і записуючим і читаючим процесом перш, ніж можна буде записувати й читати з нього дані.

Функція mkfifo визначена в заголовному файлі <sys/stat.h>:

int mkfifo(const char *FILENAME, mode_t MODE)

Функція mkfifo створює FIFO-Файл із ім'ям FILENAME. Аргумент MODE задає маску доступу до файлу, ідентичну використовуваної при створенні звичайного файлу.

При успішному виконанні функції функція повертає 0, у випадку помилки вертається -1, а змінна errno у крім помилок, пов'язаних з ім'ям файлу, може приймати наступні значення:

EEXIST файл із заданим ім'ям уже існує;

ENOSPC директорій або файлова система не можуть бути розширені;

EROFS спроба створення файлу у файловій системі “тільки для читання”.

3.8 Семафори

Тріада межпроцессорных взаємодій - семафори, повідомлення й поділювана пам'ять - мають загальне керування й структуру використовуваних команд. Для кожної із цих функцій є по одній системній таблиці, що містить всі необхідні дані.

Власником виконання межпроцессорных взаємодій є їхній творець. Тільки він і суперкористувач можуть змінювати структуру відповідних взаємодій. Операції з дозволу таких змін описуються в 9-бітовому полі, нде перші три біти описують користувача, другі три - групи користувачів, а останні три біти дають дозвіл для всіх. Перший біт у кожній із тріад дозволяє читання, другий - запис у відповідні таблиці взаємодій, а третій біт не використовується.

Семафори - це засіб межпрцессных взаємодій, використовуване для установки механізму очікування й сигналу, виконуваних системними викликами wait() і wakeup().

СЕМАФОР - це тільки цифрове значення, залежно від якого будуть пробуджуватися деякі процеси.

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

СТРУКТУРИ СЕМАФОРІВ, які містять інформацію, необхожимую при установці семафора, приєднуються, від'єднуються й модифікуються точно як ОЗУ. Таблиця SEMMAP, аналогічна таблицям COREMAP і SWAPMAP, містить доступний пул семафорних структур і приєднання в цю таблицю здійснює системний виклик semget().

Структура семафора містить чотири поля:

  • SEMVAL - поточне значення семафора,

  • SEMPID - ідентифікатор останнього процесу, що працював на даному семафорі,

  • SEMNCNT- кількість процесів, що очікують, щоб SEMVAL був вище його поточного значення.

  • SEMZCNT- число процесів, що очікують обнуління SEMVAL.

Системний виклик semctl() установлює й одержує значення SEMVAL при установці семафора, що забезпечує одночасну установку всіх елементарних семафорів у мультисемафоре.

Системний виклик semop() визначає значення SEMVAL залежно від величини, певної оператором (в SEM_OP) і поточного значення SEM_OP.

Всі процеси зупиняються, якщо SEM_OP < 0, а SEMVAL < |SEM_OP| або якщо SEM_OP = 0, а SEMVAL # 0.

Якщо SEM_OP > 0, його значення додається до SEMVAL щораз, коли процес очікує на цьому параметрі доти, поки він не прийме певної величини, після чого буде розбуджений процес, проведена перевірка коректності отриманої величини й у випадку не виконання цієї умови процес знову засипає, що забезпечує контроль процесу через системний виклик semop().

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