23. týždeň

Testovací scenár 2

Ciele

  1. Zistiť, ako fungujú rúry
  2. Naučiť sa pracovať s nepomenovanými rúrami
  3. Naučiť sa pracovať s pomenovanými rúrami
  4. Po prejdení scenára prosím vyplnte dotazník

Postup

Krok 1: Rúry

Príprava

Pre prácu na cvičení si stiahnite súbor k cvičeniu.

Obsah súboru:

.
└── 06
    ├──u1_1.c
    ├──Makefile
    └──tests
       └──u1_1_test.sh

Úvod

Jedná sa o najstarší komunikačný mechanizmus vo všetkých typoch UNIX-ov.

Existujú: - nepomenované rúry - umožňujú komunikovať len príbuzným procesom. - pomenované rúry - umozňujú komunikáciu aj procesom, ktoré nie sú príbuzné.

Krok 2: Nepomenované rúry

Teória

Umožňujú komunikáciu medzi dvoma procesmi, ktoré musia byť vzájomne príbuzné. To znamená, že medzi nimi musí byť vzťah typu rodič-potomok aj keď sa nemusí jednať o bezprostredného potomka.

Princíp komunikácie pomocou nepomenovaných rúr

Údaje sa zapisujú na zapisovacom konci rúry a následne sú prečítané na čítacom konci. Jedná sa o sériovú komunikáciu - v takom poradí, v akom boli údaje zapísané na jednom konci sú na druhom prečítané.

Nevýhody:

  • jednosmerný tok dát
  • komunikácia len medzi príbuznými procesmi (vytvorené rúry zdedí každý potomok)
  • jedná sa o samosynchronizujúci prostriedok ale len v prípade jedného volania jadra pre čítanie. Ak sa čítanie rozdelí na viac volaní, tak môže dochádzať ku konfliktom medzi procesmi.

Krok 3: Pomenované rúry (FIFO)

Teória

Pomenované rúry majú podobné správanie ako nepomenované ale existujú ako záznam v súborovom systéme. Vďaka tomu vedia k ním prístupovať procesy na základe mena tohto súboru.

Poznámka

Na rozdiel od nepomenovaných rúr, pomenované rúry môžu využívať aj procesy, ktoré sú navzájom nezávislé (nejedná sa o rodičovské procesy a ich potomkov).

FIFO musí byť otvorené na oboch koncoch (zápis aj čítanie) predtým než môže odovzdávať dáta. V prípade, že nie je, tak je blokované.

Služba jadra mkfifo()

Služba jadra mkfifo() slúži na vytvorenie pomenovanej rúry.

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

int mkfifo(const char *pathname, mode_t mode);
Parametere
const char *pathname názov súboru, ktorý bude slúžiť ako referenčný bod, ktorým procesy môžu pristupovať k rúre
mode_t mode prístupové práva
Návratová hodnota
Pri úspešnom vykonaní vráti 0
Pri chybe -1.

Úloha 3.1

Pre podrobnejšie vysvetlenie služby mkfifo() navštívte manuál man 2 mkfifo

Príklad použitia:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(){
    int des_fifo;
    des_fifo = mkfifo("/tmp/my_fifo", 0777);
    printf("Hodnota premennej des_fifo je %d\n", des_fifo);
    if(des_fifo==0){
        printf("Uspesne sa podarilo vytvorit FIFO.\n");
    } 
    else{
        perror("Chyba:");
    } 
   return 0;
}
Opis kódu:

Najprv sa vytvorí pomenovaná rúra s názvom my_fifo prostredníctvom služby mkfifo(). Následne program vypíše v prípade úspešného vykonania "Uspesne sa podarilo vytvorit FIFO.".

Výstup z programu:

des_fifo je 0
Uspesne sa podarilo vytvorit FIFO

Záznam o vytvorení rúry sa dá nájsť pomocou:

ls -lF /tmp/my_fifo

Výpis vyzerá priblížne takto: (u každého sa bude líšiť)

prwxr-xr-x 1 ab123yz tuke 0 Jan 10 10:10 /tmp/my_fifo|

Na začiatku výpisu sa nachádza písmeno p. To znamená, že sa jedná o rúru. Symbol | na konci sa nachádza kvôli voľbe F príkazu ls a tiež označuje rúru.

Poznámka

V prípade, že program spustíte opäť, tak nedôjde k vytvoreniu rúry, pretože už v systéme existuje. Výstup v tom prípade bude:

des_fifo je -1
Chyba:: File exists

Vytvorenú rúru je možné odstrániť pomocou služby jadra unlink(). V prípade, aký bol uvedený v príklade použitia, je potrebné zadať:

unlink /tmp/my_fifo

Prístup k pomenovanej rúre

Pomenované rúry sú súčasťou súborového systému. Vďaka tomu je možné ich používať v príkazoch na mieste, kde sa bežne používa názov súboru.

Rozdiel medzi nepomenovanou a pomenovanou rúrou

Pomenovaná rúra Nepomenovaná rúra
existuje v podobe pomenovaného súboru existuje ako otvorený deskriptor súboru
je potrebné ju otvárať pred tým, ako sa do/z nej zapisujú/čítajú dáta dá sa s ňou pracovať len v aktuálnom procese, alebo v procese potomka

Pomenovaná rúra sa otvára/zatvára rovnakými funkciami open()/close(), ktoré boli použité pri otváraní/zatváraní súborov.

Parameter cmd môže nadobúdať hodnotu:

Správna odpoveď: IPC_STAT / IPC_SET / IPC_RMID / IPC_INFO / SHM_INFO / SHM_STAT / SHM_STAT_ANY / SHM_LOCK / SHM_UNLOCK
Nesprávna odpoveď

Záverečná úloha

Úloha 3.2

Vytvorte program, ktorý príjme ako argument reťazec znakov (ten sa automaticky uloží ako argv[1]). Následne si vytvorí pomenovanú rúru pomocou funkcie make_fifo(). K tejto rúre bude pristupovať pomocou deskriptoru (návratová hodnota funkcie make_fifo()) uloženého pod premennou file_descriptor vo funkciách write_fifo() a read_fifo(). Návratovou hodnotou funkcií write_fifo() a read_fifo() je počet zapísaných/prečítaných bytov. Vo funkcií main() po vytvorení pomenovanej rúry zapíšte do tejto rúry reťazec znakov a následne ho aj z tejto rúry prečítajte a vypíšte na štandardný výstup.

Kostra úlohy:

fifo_ex1.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PATHNAME "/tmp/my_fifo"

int make_fifo(char* pathname);
int write_fifo(int file_descriptor, char* text, int entry_size);
int read_fifo(int file_descriptor, char* buffer, int entry_size);

int main(int argc, char *argv[]){
    return 0;
}

int make_fifo(char* pathname){
    return 0;
}

int write_fifo(int file_descriptor, char* text, int entry_size){
    return 0;
}

int read_fifo(int file_descriptor, char* buffer, int entry_size){
    return 0;
}

Zdroje

  1. DOTAZNÍK