FiFo potoki

Podstawy

Nazwany potok pracuje podobnie jak normalny ale znacząco różni się.

Tworzenie FIFO

Istnieje kilka sposobów aby utworzyć nazwany potok. Dwie pierwsze mogą zostać wykonane bezpośrednio z powłoki.

mknod MOJEFIFO p

mkfifo a=rw MOJEFIFO

Powyższe dwie komendy wykonują to samo zadanie, z jednym wyjątkiem. Komenda mkfifo umożliwia zmianę atrybutów utworzonego FIFO. Natomiast po użyciu mknod będziemy musieli w tym celu uruchomić chmod.

FIFO może być szybko zidentyfikowane poprzez literkę 'p' w listingu:

$ ls -l MYFIFO

prw-r--r-- 1 root root 0 Dec 14 22:15 MYFIFO|

Zauważ również znak potoku przy nazwie.

Aby utworzyć FIFO za pomocą C musimy posłużyć się wywołaniem systemowym mknod():

FUNKCJA Z BIBLIOTEKI: mknod();

PROTOTYP: int mknod( char *ścieżka, mode_t tryb, dev_t dev);

ZWRACA: 0 - sukces,

-1 - błąd: errno = EFAULT ( nieprawidłowa ścieżka )

EACCES ( niedozwolona operacja )

ENAMETOOLONG ( ścieżka za długa )

ENOENT ( nieprawidłowa ścieżka )

ENOTDIR ( nieprawidłowa ścieżka )

( zerknij do podręcznika mknod po więcej )

UWAGI: Tworzy węzeł w systemie plików ( plik, plik urządzenia, FIFO )

Szczegółowe omówienie mknod() pozostawię podręcznikowi, natomiast my zajmiemy się prostym przykładem tworzenia FIFO w C:

mknod("/tmp/MOJEFIFO", S_IFIFO|0666, 0);

W tym wypadku zostanie utworzony jako FIFO plik '/tmp/MOJEFIFO'. Żądanymi prawami dostępu są '0666', jednakże zależą one również od ustawienia umask w następujący sposób:

końcowe_prawa = żądane_prawa & ~oryginalny_umask

Trikiem na obejście tego jest użycie umask() w celu tymczasowego ustawienia wartości umask:

umask(0);

mknod("/tmp/MOJEFIFO", S_IFIFO|0666, 0);

Trzeci argument mknod() jest ignorowany, chyba że tworzymy plik urządzenia. W takim wypadku służy on do ustawienia głównego i podrzędnego numeru pliku urządzenia.

Operowanie FIFO

Operacje We/Wy na FIFO są właściwie takie same jak dla normalnych potoków, z jednym wyjątkiem - musimy użyć wywołania lub funkcji 'open' w celu fizycznego otwarcia kanału do potoku. Używając potoków nie musieliśmy tego robić, gdyż potok rezydował w jądrze a nie w systemie plików. W naszych przykładach będziemy traktować potoki tak jak strumienie - otwieramy je za pomocą fopen(), a zamykamy za pomocą fclose().

Rozważ ten prosty proces serwera:

/*****************************************************************************

Zaczerpnięto z "Linux Programmer's Guide - Rozdział 6"

(C)opyright 1994-1995, Scott Burkett

*****************************************************************************

MODUŁ: fifoserver.c

*****************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <unistd.h>

#include <linux/stat.h>

#define FIFO_FILE "MOJEFIFO"

int main(void)

{

FILE *fp;

char readbuf[80];

/* Tworzymy FIFO jeżeli nie istnieje */

umask(0);

mknod(FIFO_FILE, S_IFIFO|0666, 0);

while(1)

{

fp = fopen(FIFO_FILE, "r");

fgets(readbuf, 80, fp);

printf("Otrzymany łańcuch: %s\n", readbuf);

fclose(fp);

}

return(0);

}

Jakoże FIFO domyślnie blokuje program, uruchom go w tle:

$ fifoserver&

Blokowanie akcji przez FIFO omówimy za chwilę. Na razie, rozważ następujący przykład prostego klienta:

/*****************************************************************************

Zaczerpnięto z "Linux Programmer's Guide - Rozdział 6"

(C)opyright 1994-1995, Scott Burkett

*****************************************************************************

MODUŁ: fifoclient.c

*****************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#define FIFO_FILE "MOJEFIFO"

int main(int argc, char *argv[])

{

FILE *fp;

if ( argc != 2 ) {

printf("UŻYCIE: fifoclient [łańcuch]\n");

exit(1);

}

if((fp = fopen(FIFO_FILE, "w")) == NULL) {

perror("fopen");

exit(1);

}

fputs(argv[1], fp);

fclose(fp);

return(0);

}

Blokowanie akcji przez FIFO

Normalnie, FIFO blokuje wykonywanie programu. Dla przykładu jeżeli otworzymy FIFO do czytania wykonywanie programu zostanie zatrzymane do czasu gdy inny proces otworzy FIFO do pisania. Oczywiście działa to również w dugą stronę. Jeżeli nie podoba nam się takie działanie musimy przekazać znacznik O_NONBLOCK wywołaniu open().

W przypadku naszego prostego serwera, który czeka w tle na klienta moglibyśmy uruchomić go w pierwszym planie, przełączyć się na inną konsolę, odpalić klienta, i przełączając się patrzeć co się dzieje.

Ohydny sygnał SIGPIPE

Należy pamiętać, iż każdy potok musi posiadać proces czytający i zapisujący. Jeżeli jakiś proces próbuje przesłać dane przez potoku nie posiadający końcówki czytającej jądro prześle sygnał SIGPIPE. Jest to konieczne gdy więcej niż dwa procesy korzystają z potoku.


Wyszukiwarka

Podobne podstrony:
potoki 17 12
3 potoki, strumienie id 33981 Nieznany (2)
Kurort Dwa Potoki - skrót, UE Katowice, Gospodardka turystyczna mgr II rok, uzdrowiskowa
Strumienie?nych i potoki (wersja robocza)
potoki, LEKARSKI, 1 rok lerkarski, Anatomia, giełdy
4 Strumienie potoki id 37998 Nieznany
potoki
3.strumienie i potoki
przekierowanie potoki filtry, java, javascript, oprogramowanie biurowe, programowanie, programowanie
Cwiczenie 4 1 Potoki i strumienie id 99498
ściąga na WMIMB mini fifo wt
płynie gówno potokiem czasem mgła otula je płynie nurtem głębokim chwiejąc się płynie gowno potokiem
Jak wykorzystać metodę FIFO do wyceny rozchodu zapasów i walut
STRUMIENIE POTOKI, █▓▓█ INFORMATYKA ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
FIFO
strumienie i potoki

więcej podobnych podstron