Контрольні питання
Назвіть різниці між іменованими та неіменованими каналами.
Розкажіть про шляхи створення іменованих програмних каналів.
Наведіть приклади створення іменованих програмних каналів непрограмним шляхом.
Наведіть приклади створення іменованих програмних каналів програмним шляхом.
Розкажіть про реалізацію технології "клієнт-сервер" за допомогою іменованих каналів в середовищі операційної системи Unix.
Як виконується робота у фоновому та оперативному режимах? Команди переведення завдань у фоновий режим, відновлення дії програми, знищення завдань за допомогою відносних та абсолютних адрес.
Поясніть призначення та роботу рядка 4 (int main(int argc, char *argv[])) у програмі 4.2.
Завдання
Отримайте у викладача текст програми 4.1. Відкомпілюйте її під іменем fifoserver. Виконайте запуск програми у фоновому режимі;
Отримайте у викладача текст програми 4.2. Відкомпілюйте її під іменем fifo_client з помилковим та безпомилковим варіантами;
Отримайте у викладача програму розв'язання квадратного рівняння. Виконайте її запуск в фоновому режимі, потім знищіть її як завдання. Виконайте повторний запуск в оперативному режимі. Зупиніть та відновіть її дію.
Підготуйте звіт по лабораторній роботі.
Зміст звіту:
короткі відповіді на контрольні питання;
призначення та робота програм fifo_client та fifo_server;
алгоритм і текст програм 4.1 та 4.2.
Лабораторна робота №5
Маніпуляції з чергами повідомлень
Мета роботи: ознайомити з чергами повідомлень та маніпуляціями над ними.
Загальні відомості
Черги повідомлень є потужним засобом обміну інформацією між процесами, але на відміну від програмних каналів припускають більш гнучку організацію взаємодій між завданнями. Насамперед це пов'язано з відсутністю існувань парних процесів для "читача" та "письменника". В програмних засобах створюється певна черга повідомлень, яка використовується як сховище повідомлень для будь-яких процесів. В даному випадку механізми для обробки інформації створюються таким чином, що до черги повідомлень можуть звертатися і "читачі" і "письменники".
Використовуючи механізми черг, зникає необхідність застосування обох каналів - одного для читання, іншого для запису (у випадках повнодуплексного зв'язку між процесами). При цьому можна обійтись однією чергою, якщо відрізняти повідомлення за типом: від клієнта до сервера чи навпаки.
Ще однією перевагою у застосуванні черг є можливість вибирання повідомлень у довільному порядку, не використовуючи методу FIFO (лабораторна робота №3). Ця особливість відкриває перспективу побудови систем з пріоритетним обслуговуванням клієнтів.
Таким чином, при формуванні черги повідомлень не використовується потокова модель даних. Кожне повідомлення має точно визначену структуру: тип та дані. В повідомленнях допустимі будь-які дані. Їх довжина задається користувачем і може бути довільною в обсязі пам'яті, відведеної під розміщення черги у момент її створення.
Ядро системи ніяк не інтерпретує змісту повідомлень, а лише забезпечує розміщення та вибирання у співвідношенні з вказаним типом. Шаблон повідомлень знаходиться у файлі msg.h:
Struct msgbuf {
long mtype; // тип повідомлення
char mtext[1]; // дані
}
Для роботи з чергами існують такі функції (системні виклики):
msgget - створення черги;
msgetl - встановлення параметрів черги;
msgsnd - посилання повідомлення до черги;
msgrcv - одержання повідомлень з черги.
Програма 5.1 демонструє роботу з чергами (створення, встановлення параметрів та посилання повідомлень до черги), структура яких складається з двох елементів у форматах цілого та подвійного цілого чисел.
#include <stdio.h>
#include <stdlib.h>
#include <linux/ipc.h>
#include <linux/msg.h>
struct mymsgbuf {
long mtype; /* Значення номера черги */
int request; /* Перший елемент */
double salary; /* Другий елемент */
} msg;
int open_queue (key_t keyval);
int send_message (int gid, struct mymsgbuf *qbuf);
void main(void)
{
int qid;
key_t msgkey;
/* Генерація ключового поля msgkey для IPC */
msgkey = ftok(".", 'm');
/* Відкриття та створення черги */
open_queue(msgkey);
if((qid = open_queue(msgkey)) == -1) {
perror("open_queue");
exit(1);
}
/* Надання значень для черги та її елементів */
msg.mtype = 1;
msg.request = 1;
msg.salary = 1000.00;
if((send_message( qid, &msg )) == -1) {
perror("send_message");
exit(1);
int open_queue (key_t keyval) {
int gid;
if ((gid = msgget(keyval, IPC_CREAT | 0660)) == -1) {
return (-1);
}
return (gid);
}
int send_message (int qid, struct mymsgbuf *qbuf)
{
int result, length;
length = sizeof(struct mymsgbuf) - sizeof(long);
if ((result) = msgsnd(qid, qbuf, length, 0) == -1) {
return(-1);
}
return (result);
}