Hlavní navigace

Programování pod Linuxem pro všechny (24)

Jakub Matys

Dnes se podíváme na další metodu komunikace mezi procesy. Jedná se o datové kolony neboli roury.

Datová kolona (roura) je komunikační zařízení, které umožňuje jednosměrnou komunikaci. Data zapisovaná do datové kolony jedním programem lze jiným programem bezprostředně číst. Datové kolony jsou sériová zařízení, data jsou tedy čtena přesně v tom pořadí, v jakém byla zapsána. Roury se nejčastěji používají ke komunikaci mezi nadřízeným a podřízeným procesem.

Kapacita datové kolony je omezena; pokud zapisující proces generuje data rychleji, než je proces přijímající data schopen číst, kolona není schopna ukládat více dat a proces přijímající data se zablokuje, dokud neuvolní svoji kapacitu. Když se přijímající proces pokouší číst data, ale žádná se mu nedostávají, zablokuje se, dokud se neobjeví nějaká data. Z uvedeného vyplývá, že datová kolona automaticky synchronizuje dva procesy.

Vytvoření datové kolony

Datová kolona se vytváří pomocí funkce pipe(). Argumentem je celočíselné pole o dvou prvcích. Po volání funkce se na první pozici ukládá deskriptor souboru pro čtení a na druhé pozici deskriptor souboru pro zápis.

int pipe_fds[2];
    int read_fd;
    int write_fd;

    pipe(pipe_fds);
    read_fd = pipe_fds[0];
    write_fd = pipe_fds[1];

Data zapsaná do deskriptoru read_fd mohou být čtena zpět z deskriptoru write_fd.

Komunikace mezi nadřízenými a podřízenými procesy

Když proces volá funkci fork(), jsou všechny deskriptory souborů zkopírovány do podřízeného procesu. To znamená, že datové kolony mohou spojovat spřízněné procesy, ale ne procesy nespřízněné.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

/* Zapise COUNT (pocet) kopii zprav (MESSAGES) do STREAM a pote pozastavi svoji cinnost na jednu sekundu */

void writer(const char *message, int count, FILE *stream)
{
  for(;count > 0; --count){
    /* Zapise zpravu */
    fprintf(stream, "%s\n", message);
    fflush(stream);
    sleep(1);
  }
}

/* Cte retezce z STREAM */

void reader(FILE *stream)
{
  char buffer[1024];
  /* Cte dokud nenarazi na konec retezce. fgets cte dokud nenarazi na znak noveho radku nebo end-of-line */
  while(!feof(stream) && !ferror(stream) && fgets(buffer, sizeof(buffer), stream) != NULL)
    fputs(buffer, stdout);
}

int main()
{
  int fds[2];
  pid_t pid;

  /* Vytvori rouru. Deskriptory souboru pro rouru jsou ulozeny do fds */
  pipe(fds);
  /* Duplikuje proces */
  pid = fork();
  if(pid == (pid_t) 0){
    FILE *stream;
    /* Toto je synovsky proces. Zavre svou kopii pro zapis */
    close(fds[1]);
    /* Konvertuje deskriptor souboru pro cteni na objekt typu FILE a cte z neho */
    stream = fdopen(fds[0], "r");
    reader(stream);
    close(fds[0]);
  }
  else{
    /* Toto je rodicovsky proces */
    FILE *stream;
    /* Zavre svou kopii pro cteni */
    close(fds[0]);
    /* Konvertuje deskriptor pro zapis na objekt typu FILE a zapisuje do neho. */
    stream = fdopen(fds[1], "w");
    writer("Hello, world", 5, stream);
    close(fds[1]);
  }
  return(0);
} 

Na začátku funkce main() je deklarováno celočíselné pole o velikosti 2. Funkce pipe() vytvoří datovou kolonu a do pole uloží deskriptory souborů pro čtení a zápis. Program poté pomocí funkce fork() vytvoří podřízený proces. Nadřízený proces zapíše do kolony řetězce a podřízený proces je přečte.

Po zápisu funkcí writer je vyprázdněna vyrovnávací paměť pro datovou kolonu (funkce fflush()). Jinak by totiž řetězec nemohl být okamžitě odeslán skrz datovou kolonu.

To by bylo pro dnešek vše. Příště budeme přesměrovávat standardní vstup, výstup a chybové hlášení, řekneme si něco o funkcích popen() a pclose() a vytvoříme datovou kolonu FIFO.

Našli jste v článku chybu?

28. 5. 2012 19:24

xyz (neregistrovaný)

Tak ja neviem, mám 1. vydanie z roku 1988, ale union je tam "preložené" (=poslovenčené) iba ako unión.

1. 3. 2008 10:03

Eeee (neregistrovaný)
Škoda, že Linux jde opravdu jen minimálně požít na assembler programy třeba z téhle diskuse o mikroprocesorech. Na to všechno je nutné použít padačky jménem Windows :)
Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

120na80.cz: Na ucho teplý, nebo studený obklad?

Na ucho teplý, nebo studený obklad?

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu