Zaawansowane operacje wejścia/wyjścia

Podobne dokumenty
Zaawansowane operacje wejścia/wyjścia

Zaawansowane operacje wejścia/wyjścia

Zaawansowane operacje wejścia/wyjścia

Zwielokrotnianie wejścia wyjścia

J. Ułasiewicz Łącza nienazwane, nazwane, select 1

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Gniazda. S. Samolej: Gniazda 1

4. Komunikacja pomiędzy procesami przez łącza nienazwane i nazwane

J. Ułasiewicz Łącza nienazwane, nazwane, select 1

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Krótkie wprowadzenie do korzystania z OpenSSL

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

TCP - receive buffer (queue), send buffer (queue)

Funkcje systemu Unix

Gniazda BSD. komunikacja bezpołączeniowa

4.2 Sposób korzystania z l acza

Obsługa plików Procesy

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

eć dzielona standardu POSIX

Temat zajęć: Obsługa systemu plików.

Sieciowa komunikacja procesów - XDR i RPC

Systemy Operacyjne - Operacje na plikach

Programowanie sieciowe

Iteracyjny serwer TCP i aplikacja UDP

Literatura uzupełniająca: W. Richard Stevens, Programowanie zastosowań sieciowych w systemie Unix WNT 1998

3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);

Pobieranie argumentów wiersza polecenia

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Laboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Kolejki komunikatów POSIX

Rys. 9-1 Procesy P1 i P2 komunikuję się poprzez wspólny obszar. pamięci.

Przykład aplikacji UDP

1.1 Przykład znajdowanie liczb pierwszych leżących w zadanym zakresie, tryb bezpołączeniowy

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

7. Sterowanie współbieżnością

Shared memory and messages. Functions. process 0. process 1. program 0. program 0. data 0. data 1. program 1. data 0. data 1.

Programowanie aplikacji równoległych i rozproszonych. Wykład 4

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

sposób wykonywania operacji zapisu i odczytu dane odczytywane z l acza usuwane (nie można ich odczytać ponownie),

Funkcje. Piotr Zierhoffer. 7 października Institute of Computer Science Poznań University of Technology

Gniazda - Wstęp. Oprogramowanie systemów równoległych i rozproszonych. Sposób komunikacji. Domena adresowa. olas@icis.pcz.pl

Podstawy programowania w języku C++

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Funkcje zawarte w bibliotece < io.h >

1. Kolejki komunikatów POSIX

aodczytywać zniegoza pomoc afunkcjiread, (niebuforowane funkcje wejścia/wyjścia). e sukcesem, to zwróci liczb, erzeczywiściezapisanychbajtów.

Paradygmaty programowania. Paradygmaty programowania

13. Kolejki komunikatów POSIX

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Funkcje zawarte w bibliotece < io.h >

Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Architektura typu klient serwer: przesyłanie pliku tekstowo oraz logowania do serwera za pomocą szyfrowanego hasła

Systemy Operacyjne Ćwiczenia

Ghost in the machine

Functionalization. Jeszcze o funkcjach i strukturze projektu. Marcin Makowski. 3 grudnia Zak lad Chemii Teoretycznej UJ

Pliki. Informacje ogólne. Obsługa plików w języku C

Programowanie Proceduralne

przypadków wywo lanie systemowe (funkcja systemowa) lub funkcja biblioteczna zwraca wartość 1(czasamiNULL) iprzypisujezmiennej zewn etrznej,

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Uzupełnienie dot. przekazywania argumentów

1. Kolejki komunikatów POSIX

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Łącza nienazwane(potoki)

Temat zajęć: Obsługa łączy komunikacyjnych

Wykład 1

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

Semafory, pamięć dzielona i kolejki komunikatów

Komunikacja sieciowa - interfejs gniazd

Unix: programowanie z użyciem w atków

Unix: programowanie z użyciem w atków

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Laboratorium Podstawy Przetwarzania Rozproszonego SPRAWOZDANIE z zadania SERWIS KOMPUTEROWY

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Operacje wejścia/wyjścia (odsłona druga) - pliki

Pliki. Informacje ogólne. Obsługa plików w języku C

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

5. Algorytmy serwera

przerwany proces móg l zareagować na określone zdarzenie. Można je traktować jako software owe wersje przerwań sprz etowych.

Wstęp do programowania 1

dynamiczny przydział pamięci calloc() memset() memcpy( ) (wskaźniki!! )

1: ////////// 2: // test.c. 3: ssize_t ret = read(fd, buf, nbytes);

Podział programu na moduły

Programowanie przy użyciu gniazdek

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Co nie powinno być umieszczane w plikach nagłówkowych:

Obliczenia rozproszone z wykorzystaniem MPI

Gniazda UDP. Bartłomiej Świercz. Łódź, 3 kwietnia Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda UDP

Komunikacja mi edzyprocesowa (IPC)

Programowanie Sieciowe 1

Wykład 5_2 Algorytm ograniczania liczby serii za pomocą kopcowego rozdzielania serii początkowych

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Transkrypt:

Zaawansowane operacje wejścia/wyjścia Witold Paluszyński witold.paluszynski@pwr.edu.pl http://www.kcir.pwr.edu.pl/ witold/ Copyright c 2002 2003 Witold Paluszyński All rights reserved. Niniejszy dokument zawiera materia ly do wyk ladu na temat zaawansowanych operacji wejścia/wyjścia w systemie Unix. Jest on udost epniony pod warunkiem wykorzystania wy l acznie do w lasnych, prywatnych potrzeb i może być kopiowany wy lacznie w ca lości, razem z niniejsza strona tytu low a.

Blokowanie operacji I/O Blokowanie operacji wejścia/wyjścia oznacza oczekiwanie na możliwość odczytania albo zapisania danych. Przyk lady blokowania wejścia/wyjścia: odczyt z plików urzadzeń, gdy nie ma w nich już danych (potoki, terminale, gniazdka), zapis do tych samych urzadzeń, jeśli dane nie moga być od razu przyj ete, otwarcie pliku blokuje do momentu spe lnienia pewnych warunków (np. otwarcie pliku terminala do chwili nawiazania po laczenia przez modem, otwarcie FIFO do zapisu gdy żaden proces nie ma go otwartego do odczytu, itp.), operacje na plikach z mandatory record locking, i inne. Nieblokujace wejście/wyjście Blokowanie operacji I/O można kontrolować, to znaczy można tak skonfigurować operacje wejścia/wyjścia, by w sytuacji która normalnie spowodowa laby blokowanie, funkcja wróci la od razu z kodem wskazujacym niemożność wykonania operacji. open z flaga O_NONBLOCK fcntl na otwartym deskryptorze z ta sama flaga Wtedy powrót z funkcji read/write nast epuje z b l edem wskazujacym, że operacja by blokowa la. UWAGA: można zastosować stara flag e O_NDELAY, wtedy funkcje read/write zwracaja 0, co jednak pokrywa si e z sygnalizacja EOF (System V).

Równoczesne operacje I/O Jak zorganizować operacje wejścia/wyjścia, gdy mamy np. jednocześnie kilka źróde l, z których nadchodza dane? Na przyk lad, emulator terminala, komunikujacy si e z jednej strony z użytkownikiem, a z drugiej ze zdalnym systemem: Możliwe sa nast epuj ace rozwiazania: polling: nieblokujace próby odczytu na przemian z kolejnych deskryptorów; w niektórych systemach można też użyć na gniazdkach: ioctl(fd,fionread,&nread); prze laczanie (multiplexing): funkcje select i poll asynchroniczne I/O: powiadamianie procesu przez j adro (przy pomocy sygna lu) o gotowości deskryptora do operacji I/O

I/O multiplexing Ten mechanizm nie jest obj ety norma POSIX, jednak funkcja select() istnieje w Unixach AT&T i BSD od dawna i jest dość standardowa. Funkcja poll() jest nowa, i w niektórych systemach jest zaimplementowana przez select. struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* and microseconds */ ; int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); Funkcja select() zwraca liczb e deskryptorów gotowych do operacji I/O. Po powrocie wynikajacym z up lyni ecia zadanego czasu funkcja zeruje wszystkie zbiory deskryptorów w systemie V, lecz pozostawia je niezmienione w systemie BSD. Te systemy również inaczej licza deskryptory gotowe do I/O (AT&T liczy je w sensie mnogościowym, a BSD sumuje arytmetycznie liczności wszystkich trzech zbiorów deskryptorów). Ponadto, niektóre systemy w przypadku gotowości deskryptora ustawiaja w strukturze timeval czas pozosta ly do wyczerpania (Linux). Do tworzenia odpowiednich zbiorów deskryptorów, a także sprawdzania otrzymanych wyników, istnieja makra: void FD_SET(int fd, fd_set *fdset); void FD_CLR(int fd, fd_set *fdset); int FD_ISSET(int fd, fd_set *fdset); void FD_ZERO(fd_set *fdset); Funkcja poll zapewnia podobne dzia lanie lecz inny interface programisty: struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ int poll(struct pollfd fds[], nfds_t nfds, int timeout); Tablica struktur pollfd określa wszystkie deskryptory i zdarzenia, na które chcemy oczekiwać (czas określany jest tu w milisekundach). Wartość zwracana z funkcji daje liczb e gotowych deskryptorów.

#include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> int main() { char buffer[128]; int result, nread; fd_set inputs, testfds; struct timeval timeout; FD_ZERO(&inputs); FD_SET(0,&inputs); while(1) { testfds = inputs; timeout.tv_sec = 2; timeout.tv_usec = 500000; Funkcja select przyk lad result = select(fd_setsize, &testfds, (fd_set *)0, (fd_set *)0, &timeout); switch(result) { case 0: printf("timeout\n"); break; case -1: perror("select"); exit(1); default: if (FD_ISSET(0,&testfds)) { ioctl(0,fionread,&nread); if (nread == 0) { printf("keyboard done\n"); exit(0); nread = read(0,buffer,nread); buffer[nread] = 0; printf("read %d from keyboard: %s", nread, buffer); break;

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <sys/time.h> #include <sys/ioctl.h> #include <unistd.h> Funkcja select inny przyk lad int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; int result; fd_set readfds, testfds; server_sockfd = socket(af_inet, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(inaddr_any); server_address.sin_port = htons(9734); server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); listen(server_sockfd, 5); FD_ZERO(&readfds); FD_SET(server_sockfd, &readfds); while(1) { char ch; int fd, nread; testfds = readfds; printf("server waiting\n"); result = select(fd_setsize, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *) 0); if(result < 1) { perror("server5"); exit(1); for(fd = 0; fd < FD_SETSIZE; fd++) { if(fd_isset(fd,&testfds)) { if(fd == server_sockfd) { client client_sockfd = accept(server_sockfd, 0, 0); FD_SET(client_sockfd, &readfds); printf("adding client on fd %d\n", client_sockfd);

else { ioctl(fd, FIONREAD, &nread); if(nread == 0) { close(fd); FD_CLR(fd, &readfds); printf("removing client on fd %d\n", fd); else { read(fd, &ch, 1); sleep(5); printf("serving client on fd %d\n", fd); ch++; write(fd, &ch, 1);

Asynchroniczne I/O Dla każdego deskryptora, dla którego chcemy oczekiwać na dane, należy ustawić powiadamianie przez jadro odpowiednim sygna lem. Ten mechanizm również nie jest jednak obj ety norma POSIX i jest troch e inny w systemach AT&T i BSD. AT&T Mechanizm dzia la dla wszystkich urzadzeń opartych na systemie streams. Należy ustawić sygna l sigpoll dla deskryptora funkcja ioctl(fd,i_setsig,flags), gdzie argumentem flags określa si e jakie wydarzenie powinno spowodować wys lanie sygna lu. BSD Tu mamy do dyspozycji dwa sygna ly: sigio (dla zwyk lych operacji I/O), i sigurg (dla danych out-of-band z po l aczeń sieciowych). Należy ustawić proces lub grup e procesów, która ma otrzymać sygna l dla deskryptora (funkcja fcntl z komenda F_SETOWN), oraz ustawić flag e O_ASYNC dla deskryptora (funkcja fcntl z komenda F_SETFL). W chwili otrzymania sygna lu nadal nie wiemy, który deskryptor jest gotów do wykonywania operacji I/O i musimy to i tak po kolei sprawdzać.

Odwzorowanie plików do pami eci Użycie odwzorowania pliku do pami eci pozwala wykonywać operacje I/O na pliku przez manipulacje na pami eci. Zamiast przesuwać kursor pliku funkcja lseek, wystarczy obliczyć inny adres w pami eci. Odwzorowanie realizuje funkcja mmap. Poniższe wywo lanie powoduje odwzorowanie sekcji otwartego pliku fildes od pozycji off o d lugości len do obszaru pami eci od adresu addr. Adres ten może być określony jako 0, wtedy funkcja sama wybiera obszar pami eci i zwraca jego adres. pa = mmap(addr, len, prot, flags, fildes, off); Argument prot określa prawa dost epu do regionu pami eci i musi być zgodny z trybem otwarcia pliku. Argument flags określa różne atrybuty mapowanego regionu: MAP_SHARED operacje zapisu do pami eci powoduja zapis do pliku MAP_PRIVATE operacje zapisu do pami eci nie powoduja modyfikacji pliku tworzona jest robocza kopia pliku MAP_FIXED wymusza przydzia l adresu zadany argumentem (normalnie jest on tylko wskazówka dla jadra) MAP_FILE flaga wymagana w systemie BSD Operacje I/O na plikach odwzorowanych do pami eci Wykonywanie operacji I/O przez odwzorowana pami eć pozwala na wykorzystanie kana lów DMA, co daje duża szybkość operacji I/O i odciażenie g lównego procesora. Jeśli różne procesy odwzoruja ten sam plik do swoich przestrzeni adresowych, to uzyskuja dzi eki temu obszar pami eci pozwalajacy na komunikacj e mi edzyprocesow a. Ze wzgl edu na efektywność, system nie wykonuje natychmiast operacji I/O wynikajacych z zapisów do odwzorowanej pami eci. Można wymusić wykonanie tych operacji funkcja msync(). Synchronizacj e można wywo lać w dowolna stron e, tzn. zarówno zapis zawartości pami eci do pliku, jak i wczytanie zawartości pliku do pami eci. Zwyk le zamkni ecie odwzorowanego pliku nie kasuje odwzorowania mmap, należy w tym celu wywo lać: res = munmap(addr, len); Skasowanie odwzorowania nie powoduje żadnych operacji I/O do pliku. Zapis do pliku w trybie MAP_SHARED odbywa si e na bieżaco w trakcie operacji na obszarze pami eci.

Odwzorowanie pami eci przyk lady #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> /* mmap() */ #include <fcntl.h> #ifndef MAP_FILE /* 44BSD defines this & requires it to mmap files */ #define MAP_FILE 0 /* to compile under systems other than 44BSD */ #endif int main(int argc, char *argv[]) { int fdin, fdout; char *src, *dst; struct stat statbuf; if (argc!= 3) err_quit("usage: a.out <fromfile> <tofile>"); if ( (fdin = open(argv[1], O_RDONLY)) < 0) /*... */; if ( (fdout = open(argv[2], O_RDWR O_CREAT O_TRUNC, FILE_MODE)) < 0) /*... */; if (fstat(fdin, &statbuf) < 0) /* need size of input file */; if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) err_sys("lseek error"); if (write(fdout, "", 1)!= 1) /* set size of output file */ err_sys("write error"); if ( (src = mmap(0, statbuf.st_size, PROT_READ, MAP_FILE MAP_SHARED, fdin, 0)) == (caddr_t) -1) err_sys("mmap error for input"); if ( (dst = mmap(0, statbuf.st_size, PROT_READ PROT_WRITE, MAP_FILE MAP_SHARED, fdout, 0)) == (caddr_t) -1) err_sys("mmap error for output"); memcpy(dst, src, statbuf.st_size); /* does the file copy */ exit(0);

typedef struct { int integer; char string[12]; RECORD; #define NRECORDS (100) int main() { RECORD record, *mapped; int i, f; FILE *fp; fp = fopen("records.dat","w+"); for(i=0; i<nrecords; i++) { record.integer = i; sprintf(record.string,"record-%d",i); fwrite(&record,sizeof(record),1,fp); fclose(fp); fp = fopen("records.dat","r+"); fseek(fp,43*sizeof(record),seek_set); fread(&record,sizeof(record),1,fp); record.integer = 143; sprintf(record.string,"record-%d",record.integer); fseek(fp,43*sizeof(record),seek_set); fwrite(&record,sizeof(record),1,fp); fclose(fp); f = open("records.dat",o_rdwr); read(f,&record,sizeof(record)); mapped = (RECORD *)mmap(0, NRECORDS*sizeof(record), PROT_READ PROT_WRITE, MAP_SHARED, f, 0); mapped[43].integer = 243; sprintf(mapped[43].string,"record-%d",mapped[43].integer); msync((void *)mapped, NRECORDS*sizeof(record), MS_ASYNC); munmap((void *)mapped, NRECORDS*sizeof(record)); close(f); exit(0);

#include <sys/types.h> #include <stropts.h> Przekazywanie otwartych deskryptorów int send_fd(int clifd, int fd) { char buf[2]; /* send_fd()/recv_fd() 2-byte protocol */ buf[0] = 0; /* null byte flag to recv_fd() */ if (fd < 0) { buf[1] = -fd; /* nonzero status means error */ if (buf[1] == 0) buf[1] = 1; /* -256, etc. would screw up protocol */ else { buf[1] = 0; /* zero status means OK */ if (write(clifd, buf, 2)!= 2) if (fd >= 0) if (ioctl(clifd, I_SENDFD, fd) < 0) return(0); int send_err(int clifd, int errcode, const char *msg) { int n; if ( (n = strlen(msg)) > 0) if (writen(clifd, msg, n)!= n) /* send the error message */ if (errcode >= 0) errcode = -1; /* must be negative */ if (send_fd(clifd, errcode) < 0) return(0);

#include <sys/types.h> #include <stropts.h> int recv_fd(int servfd, ssize_t (*userfunc)(int, const void *, size_t)) { int newfd, nread, flag, status = -1; char *ptr, buf[maxline]; struct strbuf dat; struct strrecvfd recvfd; for ( ; ; ) { dat.buf = buf; dat.maxlen = MAXLINE; flag = 0; if (getmsg(servfd, NULL, &dat, &flag) < 0) err_sys("getmsg error"); nread = dat.len; if (nread == 0) { err_ret("connection closed by server"); for (ptr = buf; ptr < &buf[nread]; ) { if (*ptr++ == 0) { if (ptr!= &buf[nread-1]) err_dump("message format error"); status = *ptr & 255; if (status == 0) { if (ioctl(servfd, I_RECVFD, &recvfd) < 0) newfd = recvfd.fd; /* new descriptor */ else newfd = -status; nread -= 2; if (nread > 0) if ((*userfunc)(stderr_fileno, buf, nread)!= nread) if (status >= 0) /* final data has arrived */ return(newfd); /* descriptor, or -status */