<stdio.h> <iostram> input. FILE *stdin. std::cin output. std::cout error. FILE *stdout. FILE *stderr
|
|
- Angelika Wrona
- 5 lat temu
- Przeglądów:
Transkrypt
1 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Rodzina systemów POSIX zaopatrzona została w mechanizm tworzenie międzyprocesowych łączy komunikacyjnych pomiędzy procesami, zwanych potokami: nienazwanymi a więc istniejącymi wyłącznie w pamięci jądra obiektów tymczasowych, tworzonymi obok otwieranych w momencie inicjowania procesu strumieni standard input, output i error; <unistd.h> <stdio.h> <iostram> input STDIN_FILENO FILE *stdin std::cin output STDOUT_FILENO FILE *stdout std::cout error STDERR_FILENO FILE *stderr std::cerr std::clog nazwanymi, czyli posiadających dowiązanie w systemie plików, do których odwołania następując explicite przez nazwę a czas ich istnienia nie jest ograniczony czasem wykonania procesu. Każdemu z tych strumieni system operacyjny przypisuje deskryptor pliku, który stanowi unikalna liczbą całkowitą 0, 1, 2, 3, itd choć trzy pierwsze są przypisane standardowym strumieniom wejściowemu, wyjściowemu i błędu. Służą one procesowi identyfikacji i odwołaniom, przy czym procesy potomne dziedziczą te deskryptory po procesach macierzystych. Liczba możliwych do wykorzystania przez proces deskryptorów, a więc i ilość otwartych plików jest ograniczona. 1
2 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W gruncie rzeczy można byłoby się zawahać na ile w przypadku problematyki współbieżności, czy rozpatrywanej tu wieloprocesowości zasadne są takie rozwiązania. W końcu, każdy proces potomny stanowi dokładną kopię procesu macierzystego, czy w takim razie nie łatwiej uzyskać komunikację między procesową poprzez zdefiniowane już w obrębie kodu zmienne (chociażby globalne). Okazuje się jednak że całość nie przedstawia się aż tak prosto, co pokazuje wprost kolejny przykład. Rozważmy hipotetyczną sytuację, że w procesie głównym z pewnego powodu zaistniała potrzeba obliczania wartość całek funkcji jednej zmiennej. W rozpatrywanym konkretnie przypadku jest to całka 1 I = sin 2 x e x dx 0 której wartość, obliczona na drodze analitycznej wynosi I =2 1 e = Równocześnie może pojawić się sytuacja, że wyrażenie podcałkowe stanowić będą także i inna funkcja. W zawiązku z czym, logicznym rozwiązaniem byłoby wprowadzenie dodatkowej funkcji, która umożliwi obliczenie wartości całki drogą kwadratury numerycznej. 2
3 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Postać jej deklaracji nagłówkowej można by przyjąć następująco double quad( unsigned int n,double a,double b, double (*fun)(double) ); gdzie: unsigned int n ilość węzłów kwadratury double a, a b granice całkowania double fun() wskazanie do funkcji stanowiącej wyrażenie podcałkowe Istnieje wiele skutecznych metod obliczania kwadratur numerycznych, gdyby przyjąć tutaj przykładowo metodę trapezów, to b a gdzie: f x dx b a 2n f x 0 2 f x 1 2 f x k 2 f x n 1 f x n x 0 =a ; x n =b; x k =a b a k, k =0,1,2,,n n 3
4 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Samą funkcję kwadratury numerycznej możemy więc zdefiniować jak niżej. double quad( unsigned int n, double a, double b, double (*fun)(double) ) { unsigned int k; double xk, sum; sum = fun( a ) + fun( b ); for( k=1;k<n;k++ ) { xk = a+ (b-a)*k/n; sum += 2.0*fun( xk ); return ( (b-a)/(2.0*n)*sum ); Ponieważ proces macierzysty ma również i wiele innych zadań do wykonania, obliczenia wartości będą przekazane do utworzonego w tym celu procesu potomnego. 4
5 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Kod źródłowy może przedstawiać się następująco. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <math.h> int main( void ) { int pid,status; double sine( double ); double quad( unsigned int,double,double,double (*)(double)); unsigned int n; double a,b,i; Inicjujemy wartości początkowe zmiennych a=0.0; b=1.0; I=0.0; i jeszcze ilość węzłów kwadratury n=3200; 5
6 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Wywołaniem funkcji fork() duplikujemy bieżący proces i różnicujemy kod. switch( (int)fork() ) { case -1: perror( "<!> błąd inicjacji potomka" ); exit( 1 ); break; case 0: Obliczamy całkę, ale już w potomku I = quad( n,a,b,sine ); Dla pewności wyprowadzamy informację o tym co wyliczyliśmy printf( "[%d] wartość całki\t%16.6f\n",(int)getpid(),i );... i kończymy działanie potomka exit( 0 ); Teraz kod dla procesu nadrzędnego default: Powiedzmy, że coś tutaj ważnego się dzieje printf( "[%d] wykonuje ważne rzeczy...\n",(int)getpid() ); Oczekiwanie na wynik z potomka pid = (int)wait( &status );... i mamy gotowy rezultat printf( "[%d] zakończył z kodem %d\n",pid,status ); printf( "[%d] otrzymał wartość\t%16.6f\n",(int)getpid(),i ); Na tym program kończy działanie return 0; 6
7 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Oczywiście w kodzie musimy uzupełnić jeszcze definicję funkcji podcałkowej przedstawia się ona bardzo elementarnie double sine( double x ){ return sin( 2*M_PI*x )*exp(-x); Kompilacja i konsolidacja $ gcc -Wall integra.c -o integra -lm zwróćmy uwagę na dyrektywę -lm nakazującą konsolidację z biblioteką matematyczną libm.so a efekt wykonania [12401] wartość całki [12400] wykonuje, ważne rzeczy... [12401] zakończył z kodem 0 [12400] otrzymał wartość a więc nieco zaskakujący. Mimo, że utworzony proces potomny wywiązał się z zadania dobrze uzyskując bardzo dobre przybliżenie wobec wartości dokładnej (wyliczonej na drodze analitycznej) jednak proces nadrzędny tej wartości nie otrzymał, w jego przypadku wartość zmiennej I, pozostała równa wartości inicjującej. Stało się tak, ponieważ każdy proces posiadał własną, prywatną, kopię zmiennej, stąd i ich wartości końcowe są różne. Natomiast sama komunikacja międzyprocesowa nie przedstawia się aż tak elementarnie a wymaga specjalnych mechanizmów. 7
8 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Wróćmy w takim razie do kwestii użycia łączy na początek nienazwanych które mogą stanowić użyteczne narzędzia rozwiązania problemu komunikacji międzyprocesowej. Umożliwiają one asynchroniczną wymianę danych między pokrewnymi procesami a więc mającymi wspólnego przodka, bądź między bezpośrednio miedzy przodkiem a potomkiem (i odwrotnie). Jak wspomniano to już na wstępie, są realizowane jako obiekty tymczasowe w obszarze pamięci jądra, w ten sposób że dodawane są nowe pozycje do tablicy deskryptorów otwartych plików. OBSZAR PAMIĘCI JĄDRA proces łącze proces W obrębie danego łącza przepływ odbywa się zawsze w jednym kierunku (half duplex), w konsekwencji proces piszący musi na wstępie zamknąć odczyt a czytający zapis. Jeżeli komunikacja międzyprocesowa wymaga także kierunku zwrotnego, to konieczne jest otwarcie dwóch łączy. Łącza nienazwane nie są objęte standardem ISO/ANSI C lecz POSIX. De facto łącza nienazwane pipe stanowią wczesną postać UNIX System IPC (omawianego na późniejszych zajęciach). 8
9 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Komunikacja międzyprocesowa za pośrednictwem potoków może być realizowana zarówno z poziomu kodu źródłowego jak i poziomu instrukcji systemowej, a obecne było w systemach UNIX'opodobnych praktycznie od momentu ich powstania. Realizowane jest za pośrednictwem operatora przetwarzania potokowego, który łączy standardowe wyjście jednego procesu ze standardowym wejściem innego. Przykładowo $ ls -l /usr/bin/ cat -n tail -n rwxr-xr-x 1 root root 3652 lis znew 2387 lrwxrwxrwx 1 root root 8 kwi zsh -> /bin/zsh rwxr-xr-x 1 root root kwi zsoelim rwxr-xr-x 1 root root lis zvbi-chains rwxr-xr-x 1 root root lip zypper Użyto tutaj trzech instrukcji systemowych ls -l /usr/bin listing katalogu /usr/bin w formacie long cat -n wyświetla zawartość wejście dodając numerację linii tail -n 5 wyświetla 5 ostatnich linii ze strumienia na wejściu ustanawiające między ich standardowymi wyjściami a wejściami dwa łącza nienazwane (symbol ' '). 9
10 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Korzystając z API systemowego POSIX otwarcie łącza następuje wywołaniem funkcji pipe() zaś zamknięcie close(). Synopsis #include <unistd.h> int pipe( int fd[2] ); int fd[0] zawiera numer deskryptora do odczytu int fd[1] zawiera numer deskryptora do zapisu int close( int fd ); int fd numer deskryptora do zamknięcia Return 0 operacja zakończona powodzeniem Errors -1 Odczyt/zapis z/do potoku odbywa się za pośrednictwem pary funkcji read() i write(). Synopsis #include <unistd.h> ssize_t read( int fd, void *buf, size_t count ); ssize_t write( int fd, const void *buf, size_t count ); void* buf obszar pamięcie do odczytu/zapisu size_t count ilość bajtów do odczytu/zapisu Return ilość bajtów przeczytana / zapisana Errors -1 10
11 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Jako elementarną ilustrację przygotujemy program, który utworzy proces potomny, wysyłający do macierzystego zwrotną wiadomość. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/limits.h> int main( void ) { int fd[2],n; PIPE_BUF jest predefiniowaną stała dla bufora systemowego pipe() char line[pipe_buf]; Próbujemy ustanowić połączenie (nienazwane) if( pipe( fd )< 0 ) { printf( "...błąd otwarcia łącza\n" ); exit( 1 ); Tworzymy proces potomny switch( fork() ) { Na wypadek ewentualnego niepowodzenia case -1: perror( "<!> błąd inicjacji potomka" ); exit( 1 ); break; 11
12 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Jeżeli fork() zakończył się sukcesem, to dla procesu potomnego case 0: Na początek zamykamy kanał od strony odczytu close( fd[0] ); bowiem będziemy do niego pisać write( fd[1],"\n\t[pozdrowienia od potomka]\n\n",29 ); W zasadzie to zamknięcie jest zbędne close( fd[1] ); ponieważ po wykonaniu exit() system i tak zamknie kanał od strony potomka exit( 0 ); Natomiast kod dla procesu nadrzędnego default: Tu natomiast zamykamy zapis close( fd[1] ); Czytamy teraz to co wcześniej wysłał potomek n = read( fd[0],(void*)line,pipe_buf ); //close( fd[0] ); Wypisujemy co otrzymaliśmy od potomka na STDOT write( STDOUT_FILENO,line,n ); return 0; 12
13 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Zauważmy, że celem wyprowadzenia informacji wykorzystano tutaj jeden ze standardowo predefinowanych deskryptorów #define STDOUT_FILENO 1 /* Standard output. */ #define STDERR_FILENO 2 /* Standard error output. */ które otwierane są dla każdego procesu, w momencie jego tworzenia, przez system. Definicje znajdują się w pliku unistd.h. Rozmiar bufora zdefiniowano za pomocą stałej PIPE_BUF zdefiniowanej /linux/limits.h Jej wartość określa maksymalny rozmiar dla przesyłanej porcji danych potokiem nienazwanym, tak aby operacja ta była atomowa a więc niepodzielna. Zgodnie z definicją #define PIPE_BUF 4096 Obok niej istnieje także definicja stałej POSIX (posix1_lih.h), o identycznym sensie #define _POSIX_PIPE_BUF 512 choć innej (znacznie mniejszej) wartości. Inaczej niż zwykle, w kodzie procesu macierzystego nie użyto funkcji wait(). Było to możliwe ponieważ wywołanie read() ma charakter blokujący. Domniemanie to można zmienić wykorzystując funkcję fcntl() i ustawiając znacznik O_NONBLOC dla uzyskanego wcześniej deskryptora. Wymagałoby to jednak użycia funkcji wait(). 13
14 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Wracając teraz do problemu przedstawionego na wstępie potomka który wykonywał na rzecz procesu nadrzędnego obliczenia kod programu powinien się przedstawiać jak w listingu. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <math.h> int main( void ) { int pid,status; double sine( double ); double quad( unsigned int, double, double,double (*)(double) ); unsigned int n; double a,b,i; int fd[2]; a=0.0,b=1.0,i=0.0; n=3200; if(pipe(fd)<0){ printf("...błąd otwarcia łącza\n"); exit(1); 14
15 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Teraz dopiero tworzymy proces potomny. switch( fork() ) { case -1: perror( "<!> błąd inicjacji potomka" ); exit( 1 ); break; case 0: close( fd[0] ); I = quad( n,a,b,sine ); printf( "[%d] wartość całki %19.6f\n",(int)getpid(),I ); write( fd[1],(void*)&i,sizeof( double ) ); exit( 0 ); default: close( fd[1] ); printf( "[%d] wykonuje, ważne rzeczy...\n",(int)getpid() ); read( fd[0],(void*)&i,sizeof( double ) ); printf( "[%d] zakończył z kodem %d\n",pid,status ); printf( "[%d] otrzymał wartość %16.6f\n",(int)getpid(),I ); return 0; Oczywiście funkcje sine() i quad() nie wymagają żadnych zmian. 15
16 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Efekt wykonania będzie następujący $ integral [4225] wartość całki [4224] wykonuje, ważne rzeczy... [4225] zakończył z kodem 0 [4224] otrzymał wartość a więc komunikacja między procesami przebiegła bez zakłóceń a wynik otrzymany przez proces nadrzędny poprawny. 16
17 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Ponieważ proces może utworzyć wiele potoków w postaci łączy nienazwanych, a z reguły (w większości implementacji) jak zaznaczono to na wstępie, są one jednokierunkowe, bardzo użytecznymi mogą okazać się funkcje dup() i dup2(). Synopsis #include <unistd.h> int dup( int old ); int dup2( int old, int new ); int old istniejący, utworzony uprzednio wywołaniem pipe(),, deskryptor int new nowy deskryptor na który zostanie skopiowany (skojarzony) old Return nowy deskryptor Errors -1 Tak więc efektem wywołanie obu funkcji będzie utworzenie kopii deskryptora, z tą różnicą że w przypadku dup2() mamy możliwość wskazania w sposób jawny na co skopiować. Funkcja dup() zwraca natomiast najniższy, pierwszy wolny. 17
18 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W kolejnym przykładzie z procesu macierzystego wyślemy kilka linii tekstu, które w procesie potomnym zostaną posortowane za pomocą programu sort (systemowy). Przy okazji użyjemy tu w relacji do łącza nienazwanego funkcji przeznaczonych do działania na strumieniu skojarzonym z plikiem. #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> int main () { int fd[2]; int pid,status; Ta zmienna zostanie w przyszłości skojarzona z potokiem FILE* stream; if( pipe( fd )< 0 ) { printf( "...błąd otwarcia łącza\n" ); exit( 1 ); 18
19 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W takim razie tworzymy proces potomny switch( (pid=(int)fork()) ) { case -1: perror( "<!> błąd inicjacji potomka" ); exit( 1 ); break; Kod dla potomka case 0: Na początek powitanie printf( "<!>\tpotomek [%d] startuje\n",(int)getpid() ); Zamykamy fd[1] bo potomek nie będzie pisał do potoku close( fd[1] ); Kopjujemy potomkowi fd[0] potoku na jego stdin dup2( fd[0],stdin_fileno ); Zamykamy fd[0], bo już niepotrzebne skopiowaliśmy na stdin close(fd[0]); Teraz pozostaje już tylko wywołać program sort printf(" \n" ); execl( "/usr/bin/sort","sort","--reverse",(char*)null ); Zauważmy że program uruchomiony przez execl() odziedziczył wejście stdin po potomku, a więc przekierowane fd[0]. 19
20 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Teraz kod dla procesu macierzystego. default: Zamykamy od tej strony kanału odczyt, bo będziemy pisać. close( fd[0] ); Przypisanie strumienia (plikowego) istniejącemu deskryptorowi. stream = fdopen( fd[1], "w" ); Piszemy do kanału, na końcu którego jest potomek (właściwie to sort). fprintf( stream, "\taaaaa\n" ); fprintf( stream, "\tbbbbb\n" ); fprintf( stream, "\tccccc\n" ); fprintf( stream, "\tddddd\n" ); Na wszelki wypadek opróżniamy bufor plikowy fflush( stream ); Zamykamy deskryptor, ponieważ nie jest dłużej potrzebny close( fd[1] ); i czekamy na potomka, aż skończy wait( &status ); Po zakończeniu wyświetlamy komunikat pintf(" \n" ); printf("<!>\tpotomek [%d] zakończył działanie i zwrócił [%d]\n",pid,status ); return 0; 20
21 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Efekt wykonania programu przedstawia się następująco: $./duplicate <!> potomek [8269] startuje Ddddd Ccccc Bbbbb Aaaaa <!> potomek [8269] zakończył działanie i zwrócił [0] $ Użyto tutaj celem skojarzenia deskryptora ze strumieniem - dodatkowo funkcji fdopen() i fflush(). #include <stdio.h> int fflush( FILE *stream ); FILE *fdopen( int fildes, const char *mode ); Tryb mode może być określony jako r (odczyt), r+ w+ (odczyt lub zapis), a (rozszerzenie, czyli pisanie na końcu pliku), a+ (rozszerzenie lub czytanie). 21
22 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Mechanizm łączy nienazwanych można z powodzeniem wykorzystać do komunikacji dwukierunkowej, między procesem nadrzędnym a potomnym. Kolejny przykład pokazuje tego rodzaju wariant komunikacji międzyprocesowej. Złóżmy, że proces nadrzędny prześle do procesu potomnego pewną wartość x oczekując na wykonanie na niej pewnej operacji f(x)=y a proces potomny zwróci do procesu nadrzędnego wynik tej operacji, czyli y. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main( void ) { int pid,status; int one[2],two[2]; double x=1.0,y=1.0; printf( "\t[%d] nadrzędny, start\n\n",(int)getpid() ); Oczywiście, w przypadku komunikacji dwukierunkowej, konieczne są dwa kanały if( pipe( one )< 0 pipe( two )<0 ) { printf( "<!> błąd otwarcia łączy\n" ); exit( 1 ); 22
23 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. switch( pid=(int)fork() ) { Gdyby coś poszło nie tak case -1: perror( "<!> błąd inicjacji potomka" ); exit( 1 ); break; Teraz kod dla potomka case 0: Powitanie printf( "\t[%d] potomek, start\n\n",(int)getpid() ); Zamykamy niepotrzebne deskryptory, odpowiednio do kierunku przesyłu close( one[1] ); close( two[0] ); Czytamy to co nadrzędny ma nam do powiedzenia read( one[0],(void*)&x,sizeof( double ) ); printf( "\t[%d] otrzymał x=%f\n",(int)getpid(),x ); Wykonujemy właściwe operacje, na rzecz nadrzędnego y = x*m_pi; printf( "\t[%d] wykonał f(x)=y, wysyła y=%f\n",(int)getpid(),y ); no i w końcu wysyłamy wynik końcowy do nadrzędnego write( two[1],(void*)&y,sizeof( double ) ); printf( "\t[%d] potomek, stop\n\n",(int)getpid() ); exit( 0 ); 23
24 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. A teraz kod dla procesu nadrzędnego default: Oczywiście zamykamy to co nie jest nam potrzebne close( one[0] ); close( two[1] ); Wysyłamy dane do potomka printf( "\t[%d] wysyła do potomka [%d] x=%f\n\n",(int)getpid(),pid,x ); write( one[1],(void*)&x,sizeof( double ) ); no i czekamy na wynik do potomka read( two[0],(void*)&y,sizeof( double ) ); wait( &status ); printf( "\t[%d] potomek, zwrócił sterowanie, kod powrotu [%d]\n",pid,status ); informacja diagnostyczna printf( "\t[%d] otrzymał y=%f\n",(int)getpid(),y ); printf( "\n\t[%d] nadrzędny, stop\n",(int)getpid() ); Proces nadrzędny kończy ostatecznie działanie return 0; 24
25 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Efekt wykonanie programu przedstawia się następująco $ bidir [7810] nadrzędny, start [7811] potomek, start [7810] wysyła do potomka [7811] x= [7811] otrzymał x= [7811] wykonał f(x)=y, wysyła y= [7811] potomek, stop [7811] potomek, zwrócił sterowanie, kod powrotu [0] [7810] otrzymał y= [7810] nadrzędny, stop [7810] nadrzędny, stop $ 25
26 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Prócz ewidentnych zalet i korzyści wynikających z użycia w komunikacji międzyprocesowej łączy nienazwanych, mimo wszystko nie zawsze warto je stosować. Zasadniczym utrudnieniem w przypadku łączy nienazwanych jest kwestia współużytkowania takiego łącza przez procesy niespokrewnione. W takiej sytuacji zwykle lepszym wyborem będą łącza w postaci potoku nazwanego (named pipe). W odróżnieniu od łącze nienazwane: jest identyfikowane przez nazwę i może z niego korzystać (o ile ma odpowiednie prawa dostępu) wiele procesów (nawet nie spokrewnionych); posiada organizację FIFO, czyli First In First Out, stąd i ich skrótowa nazwa; posiada dowiązanie w systemie plików (jako plik specjalny urządzenia) aż do momentu ich jawnego usunięcia; mimo iż zachowuje cechy pliku de facto jak wyjaśnia to dokumentacja systemowa LINUX: is a window into the kernel memory that "looks" like a file. Podobnie jak i łącza nienazwane mogą być tworzone w dwojaki sposób: z poziomu systemowego interface'u użytkownika albo wywołaniem funkcji API z procesu (czy wątku). 26
27 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Z poziomu interface systemowego łącza nazwane FIFO tworzone są komendą $ mkfifo -m mode name mode maska praw dostępu, czyli symbolicznie dla u (user), g (group), o (other), a (all) dodaje (+),, ujmuje (-) od istniejących lub ustawia (=) prawo r (read), w (zapis), x (execute) name nazwa pliku specjalnego FIFO, ewentualnie wraz ze ścieżką zaś jego usunięcie odbywa się w identyczny sposób jak każdego pliku dyskowego, a więc $ rm name Utwórzmy w takim razie przykładowe łącze FIFO $ mkfifo a=rw /tmp/km-fifo Jeżeli wykonamy teraz $ ls -l /tmp/km-* prw-r--r-- 1 kmirota users 0 maj 22 12:09 /tmp/km-fifo Zwróćmy uwagę na opis dowiązania, zgodnie ze specyfikacją dla ls - Regular file l Symbolic link b Block special file n Network file c Character special file p FIFO d Directory s Socket czyli powstało FIFO pipe. 27
28 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Takie cechy "pliku" km-fifo potwierdza także, w szczegółach, komenda stat $ stat /tmp/km-fifo File: `/tmp/km-fifo` Size: 0 Blocks: 0 IO Block: 4096 potok Device: 806h/2054d Inode: Links: 1 Access: (0644/prw-r--r--) Uid:(1000/kmirota) Gid:(100/users) Access: :35: Modify: :35: Change: :35: Otwórzmy teraz dwie sesje terminala, w oknie pierwszego pierwszego wpisujemy $ cat < /tmp/km-fifo czyli przekierujemy zawartość km-fifo na wejście komendy systemowej cat. Ta, jak wiadomo, wyświetla na swoim wyjściu (czyli tutaj w oknie terminala pierwszego), to co otrzyma na wejściu. Teraz przełączamy się na drugie okno terminala, i wykonujemy $ cat > /tmp/km-fifo czyli w przeciwnym kierunku, zatem wejście drugiego terminala zostało przekierowane na plik km-fifo. Efekt będzie taki, że cokolwiek wprowadzimy w oknie terminala drugiego, natychmiast zobaczymy w oknie pierwszego. Zauważmy że plik tem będzie miał przez cały czas rozmiar zerowy. Całość można zakończyć przesyłając do cat kod EOF (End Of File), czyli z klawiatury <Ctrl>-d. 28
29 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Jeżeli na pierwszym terminalu ponownie wykonamy przekierowanie $ cat < /tmp/km-fifo zaś na drugim przekierujemy do pliku km-fifo wykonanie jakiejkolwiek komendy, przykładowo $ stat /tmp/km-fifo >/tmp/km-fifo to na pierwszym zobaczymy oczywiście File: `/tmp/km-fifo' Size: 0 Blocks: 0 IO Block: 4096 potok Device: 806h/2054d Inode: Links: 1 Access: (0644/prw-r r--) Uid: (1000/kmirota) Gid:(100/users) Access: :53: Modify: :53: Change: :53: $ i w tym momencie potok zostanie automatycznie zamknięty, bowiem strumień przepływających danych uległ zakończeniu. Zauważmy że po zakończeniu sesji plik pozostaje w katalogu, przez cały czas posiadając rozmiar zerowy. Usuwamy go jednak jak każdy plik $ rm /tmp/km-fifo 29
30 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W systemach rodziny POSIX łącza nazwane tworzone są wywołaniami funkcji mkfifo(). Synopsis #include <sys/types.h> #include <sys/stat.h> int mkfifo( const char *pathname, mode_t mode ); const char *pathname nazwa tworzonego pliku (tu: łącza) mode_t mode maska uprawnień odnośnie odczytu i zapisu Return 0 jeżeli zakończone sukcesem Errors -1 Usuwane natomiast odbywa się przy pomocy funkcji unlink(). Synopsis #include <unistd.h> int unlink( const char *pathname ); const char *pathname nazwa usuwanego pliku (tu: łącza) Return 0 jeżeli zakończone sukcesem Errors -1 30
31 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Maska uprawnień może być zadana z wykorzystaniem sumy bitowej predefiniowanych stałych w pliku nagłówkowym sys/stat.h: S_IRUSR S_IWUSR S_IXUSR dla właściciela S_IRGRP S_IWGRP S_IXGRP dla grupy, do której należy właściciel S_IROTH S_IWOTH S_IXOTH dla pozostałych lub też korzystając z stałej DEFFILEMODE, dla wszystkich łącznie #define DEFFILEMODE (S_IRUSR S_IWUSR S_IRGRP S_IWGRP S_IROTH S_IWOTH) ustawiając dla wszystkich uprawnienia do odczyty i zapisu (zwróćmy uwagę, że na efektywne uprawnienia mają wpływ stosowane ustalenia odnośnie katalogu nadrzędnego). Ponieważ łącze nazwane posiada dowiązanie do struktury plików operacje na nim przeprowadza się w zwyczajowy sposób, tak jak i w przypadku ogółu, a więc: utworzone łącze trzeba otworzyć, przed użyciem, uzyskując w ten sposób jego deskryptor albo wskazanie do obiektu typu FILE; wykonujemy odczyt lub zapis, odpowiednio do potrzeb; po wykorzystaniu łącza proces powinien zamknąć je, od swojej strony. 31
32 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Niskopoziomowe operacje otwarcia i zamknięcie wykonujemy przy pomocy open() i close(). Synopsis #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open( const char *pathname, int flags ); const char *pathname nazwa otwieranego pliku (tu: łącza) int flags maska określająca sposób korzystania: O_RDONLY O_WRONLY O_RDWR tylko odczyt, tylko zapis, odczyt lub zapis O_NONBLOCK otwarcie w trybie nieblokującym Return deskryptor pliku Errors -1 Synopsis #include <unistd.h> int close( int fd ); int fd deskryptor pliku (tu: łącza nazwanego) Return 0 zakończona sukcesem Errors -1 32
33 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Przydzielając deskryptor łączu za pośrednictwem funkcji open() trzeba pamiętać, że jej wywołanie mają zasadniczo charakter blokujący, tzn. wywołanie fd=open( pathname,o_rdonly ); będzie czekać aż jakikolwiek proces nie otworzy kolejki do zapisu fd=open( pathname,o_wronly ); będzie czekać aż jakikolwiek proces nie otworzy kolejki do odczytu Jeżeli jednak otwarcie nastąpi z użyciem maski O_NONBLOCK wówczas fd=open( pathname,o_rdonly O_NONBLOCK ); zwróci natychmiast sterowanie fd=open( pathname,o_wronly O_NONBLOCK ); także zwróci natychmiast sterowanie, jeżeli jednak nie będzie żadnego procesu, który otworzył tę kolejkę do odczytu to zamiast deskryptora otrzymamy -1 (oraz errno = ENXIO) Dysponując deskryptorem, do odczytu i zapisu, używamy read() i write(). Synopsis #include <unistd.h> ssize_t read( int fd,void *buffer,size_t bytes ); ssize_t write( int fd,const void *buffer,size_t bytes ); int fd deskryptor pliku Return void* buffer bufor do odczytu lub zapisu ilość bajtów przesłanych size_t bytes ilość bajtów do przesłania Errors -1 33
34 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Na łączu nazwanym możemy także operować w sposób bezpośredni za pomocą wysokopoziomowych funkcji ISO C standard I/O. W pierwszej kolejności należy oczywiście otworzyć łącze wywołaniem fopen(). Synopsis #include <stdio.h> FILE *fopen( const char *pathname,const char *mode ); const char *pathname nazwa otwieranego pliku (tu: łącza) char *mode tryb otwarcia pliku: r (r+ r+) odczyt (i i zapis), w (w+ w+) zapis (i i odczyt), a (a+ a+) rozszerzenie (i i odczyt) Return wskazanie do strumienia plikowego FILE Errors NULL W końcu zaś zamknąć przy pomocy fclose(). Synopsis #include <stdio.h> int fclose( FILE *stream ); FILE *stream wskazanie do strumienia, do zamknięcie Return 0 jeżeli sukces Errors EOF 34
35 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Celem odczytu i zapis z i do strumienia plikowego stosuje się głównie funkcje formatowanego wejścia/wyjścia fscanf() i fprintf(). Synopsis #include <stdio.h> int fscanf( FILE *stream,const char *format,... ); int fprintf( FILE *stream,const char *format,... ); FILE *stream wskazanie do strumienia otwartego do odczytu const char *format łańcuch formatujący zawierający wzorce konwersji, w szczególności: "%c" znak, "%s" łańcuch, "%d" liczba całkowita, "%f" liczba rzeczywista... lista zmiennych Return ilość zmiennych wczytanych skutecznie, wg listy argumentów Errors EOF Całość operacji plikowych z czego tu przedstawiono tylko drobny wycinek stanowi element normy ISO/IEC 9899:1999 "Programming languages C" 35
36 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Wejście i wyjście plikowe, z punktu widzenie programisty, przedstawia się zwykle dość korzystnie i atrakcyjnie, jednak może przysporzyć także problemów. Między innymi za sprawą stosowanych tu mechanizmów buforowania. Stąd mogą pojawić się niezgodności tego co zawarte jest w skojarzonym buforze plikowym a wartościami zmiennych, póki strumień nie zostanie zamknięty. Przykładem tego rodzaju sytuacji jest poniższy kod. #include <stdio.h> int main( void ) { printf( "1 sek " ); sleep( 1 ); printf( "2 sek " ); sleep( 1 ); printf( "3 sek " ); sleep( 1 ); printf( "4 sek " ); sleep( 1 ); printf( "5 sek " ); sleep( 1 ); printf( "i koniec\n" ); return 0; 36
37 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Nie zobaczymy wcale serii komunikatów (choć zależy to od użytego kompilatora), pojawiających się co 1 sekundę, ale wszystkie równocześnie w momencie kiedy napotkany będzie znak końca linii '\n'. 1 sek 2 sek 3 sek 4 sek 5 sek i koniec Aby osiągnąć zamierzony efekt, wyświetlanego komunikatu co sekundę należałoby użyć funkcji fflush() opróżniającej bufor plikowy, tutaj standardowego wyjścia stdout. Synopsis #include <stdio.h> int fflush( FILE *stream ); FILE *steram bufor plikowy do opróżnienia (uprzednio otwarty) Return 0 jeżeli sukces Errors EOF Zatem w przypadku rozpatrywanego kodu konieczne jest jego uzupełnienie o wywołania fflush( stdout ); w sposób ja na załączonym dalej listingu. 37
38 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. #include <stdio.h> int main( void ) { printf( "1. " ); fflush( stdout); sleep( 1 ); printf( "2. " ); fflush( stdout); sleep( 1 ); printf( "3. " ); fflush( stdout); sleep( 1 ); printf( "4. " ); fflush( stdout); sleep( 1 ); printf( "5. " ); fflush( stdout); sleep( 1 ); printf( "i koniec\n" ); return 0; O samej funkcji warto pamiętać ponieważ problem buforów plikowych w odniesieniu do łączy komunikacyjnych bywa nad wraz uciążliwy, stając się przyczyną wielu zaskakujących wyników i frustracji. Na koniec należy nadmienić że o ile użycie fflush( stdout ) jest zgodne z normą ISO, to w odniesieniu do strumienia wejściowego fflush( stdin ) już nie jest. 38
39 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Problem buforowania po stronie odczytu można także rozwiązać używając celem wczytywania funkcji "nie zaśmiecającej" tak bufor plikowy jak scanf(). Mogłaby to być w tym przypadku fgets(), która wczytuje łańcuch tekstowy, a dopiero z niego za pomocą sscanf() wczytujemy potrzebne wartości zmiennych. Synopsis #include <stdio.h> char *fgets(char *buffer, int size, FILE *stream); char *buffer bufor odczytu int size ilość znaków do wczytania, pomniejszona o 1,, na ostatniej pozycji dodawane jest '\0' (funkcja( kończy czytanie jeżeli napotka EOF lub '\n') FILE *stream otwarty do odczytu bufor plikowy Return char *buffer jeżeli sukces, to wskazanie do wyniku Errors NULL Deklaracja i użycie funkcji int sscanf( const char *buffer,const char *format,... ); jest właściwie identyczne z fscanf(), w tym że odczyt nie następuje ze strumienia plikowego ale łańcucha const char *buffer bufor w postaci łańcucha tekstowego, z którego zawartość podlega konwersji, zgodnie z łańcuchem format 39
40 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Przygotujemy teraz dwie aplikacje, które poprzez łącze nazwane pipe będą wzajemnie się komunikować. Pierwsza stanowić będzie serwer nasłuchujący danych napływających łączem, a w przypadku odebrania wyświetli komunikat. #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <unistd.h> int main( void ) { time_t stamp; pid_t pid; int fd,run; char cmd; printf("\n[%d]*s*e*r*w*e*r*[%d]\n\n",(int)getpid(),(int)getpid()); Na początek próbujemy otworzyć łącze do odczytu if( (fd=open( "pipe",o_rdonly )) >0 ){ run=1; else{ printf( "!.!..nie znaleziono łącza..!.!\n\n" ); run=0; 40
41 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W przypadku kiedy udało się uzyskać deskryptor while( run ) { Odczytujemy, od kogo pochodzi wiadomość read( fd,&pid,sizeof( pid_t ) ); następie czytamy komendę read( fd,&cmd,sizeof( char ) ); Wyświetlamy informację, od kogo, co i kiedy otrzymano stamp = time( NULL ); printf( "[%d]\t %c -> %s",(int)pid,cmd,ctime( &stamp ) ); Jeżeli odebrano komendę Q(uit), to kończymy if( cmd=='q' ){ run=0; close( fd ); return 0; Teraz kod klienta, który będzie komunikował się z naszym serwerem przez łącze pipe. 41
42 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <ctype.h> int main( void ) { int fd,run; pid_t pid; char cmd; char buffer[256]; Wyświetlamy komunikat diagnostyczny pid = getpid(); printf( "\n[%d]*k*l*i*e*n*t*[%d]\n\n",(int)pid,(int)pid ); Podobnie jak wcześniej sprawdzamy dostępność łącza if( (fd=open( "pipe",o_wronly )) >0 ){ run=1; else{ printf( "!.!..nie znaleziono łącza..!.!\n\n" ); run=0; 42
43 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Jeżeli udało się uzyskać deskryptor łącza while( run ) { Pobieramy komendę od użytkownika printf( "\t?...\t" ); fgets( buffer,256,stdin ); sscanf( buffer,"%c",&cmd ); cmd = toupper( cmd ); Piszemy do łącza write( fd,&pid,sizeof( pid_t ) ); write( fd,&cmd,sizeof( char ) ); Jeżeli użytkownik podał Q(uit), to kończymy proces klienta if( cmd=='q' ){ run=0; close( fd ); return 0; 43
44 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Zanim uruchomimy procesy serwer i klienckie, najpierw musimy utworzyć łącze. Zatem $ mkfifo pipe Sprawdźmy jeszcze wynik komendy $ ls -l razem 32 -rwxr-xr-x 1 kmirota users maj 23 10:36 klient -rw-r--r-- 1 kmirota users 697 maj 23 10:36 klient.c prw-r--r-- 1 kmirota users 0 maj 23 10:37 pipe -rwxr-xr-x 1 kmirota users maj 23 10:36 serwer -rw-r--r-- 1 kmirota users 682 maj 23 10:36 serwer.c a więc łącze pipe zostało utworzone. Otwieramy teraz dwa terminale w pierwszym uruchamiamy proces serwera a w drugim (i ewentualnie kolejnych) procesy klienckie. $./klient [8053]*K*L*I*E*N*T*[8053]?...??...??...??... q $./serwer [8052] * S * E * R * W * E * R * [8052] [8053]? -> Fri Oct 23 11:07: [8053]? -> Fri Oct 23 11:07: [8053]? -> Fri Oct 23 11:07: [8053] Q -> Fri Oct 23 11:07:
45 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Ponownie wykorzystując mechanizm łącza nazwanego przygotujemy serwer, który pozostając na końcu łącza zamknie je i będzie odsyłał zwrotnie cokolwiek dostanie. Kod źródłowy serwera przedstawia się jak na załączonym listingu. #include <stdio.h> #include <limits.h> int main( void ) { FILE *stream; char buffer[line_max]; int run; if( (stream = fopen( "channel","r+" ) ) ){ run=1; else{ run=0; perror( "!.!..błąd otwarcia łącza..!.!" ); while( run ) { if( fgets( buffer,256,stream ) ) { fprintf( stream,"%s",buffer ); fflush( stream ); return 0; 45
46 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Zwróćmy uwagą, że celem wyświetlenia informacji o ewentualnym błędzie otwarcia kanału, użyliśmy funkcji perror(), gdyż tylko ona gwarantuje że nawet w przypadku procesu pracującego w tle zobaczymy komunikat o błędzie. Początkowy fragment kodu klienta niewiele tylko różni się od przedstawionego wcześniej #include <stdio.h> #include <limits.h> #include <string.h> #include <ctype.h> int main( void ) { FILE *stream; char buffer[line_max]; int run; int empty( char* ); if( (stream = fopen( "channel","r+" ) ) ){ run=1; else{ run=0; perror( "!.!..błąd otwarcia łącza..!.!" ); 46
47 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. W dalszym fragmencie umieszczamy pętle czytającą i piszącą, do momentu kiedy użytkownik wprowadzi linię pustą. while( run ) { bzero( (void*)buffer,line_max ); fgets( buffer,line_max,stdin ); if(!empty( buffer ) ) { fprintf( stream,"%s",buffer ); fflush( stream ); else{ fclose( stream ); break; fgets( buffer,line_max,stream ); if(!empty( buffer ) ) { fprintf( stdout,"%s",buffer ); fflush( stream ); return 0; Pozostaje jeszcze dodać funkcję która będzie sprawdzać czy nie pojawił się łańcuch pusty (w naszym rozumieniu łańcuch nie zawierający ani jednej litery czy też cyfry). int empty( char * string ) { while( *string ){ if( isalnum(*string++) ){ return 0; return 1; 47
48 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Oczywiście na początek należy utworzyć właściwe łącze nazwane $ mkfifo channel i sprawdźmy $ stat channel File: `channel' Size: 0 Blocks: 0 IO Block: 4096 potok Device: 807h/2055d Inode: Links: 1 Access: (0644/prw-r r--) Uid:(1000/kmirota) Gid: (100/users) Access: :29: Modify: :29: Change: :29: Następnie uruchamiamy z bieżącego terminala proces serwera, w tle (zwróćmy uwagę na znak '&' na końcu linii komendy, który wywołuje właśnie takie uaktywnienie procesu przez system). $./serwer & [1] 8603 gdyby teraz sprawdzić listę aktywnych procesów $ ps PID TTY TIME CMD 4311 pts/1 00:00:00 bash 8603 pts/1 00:00:00 server 8607 pts/1 00:00:00 ps to jak proces o identyfikatorze 8603 pracuje nasz serwer. Jego działanie możemy w dowolnej chwili zakończyć, komendą (o ile nie będzie już potrzebny) $ kill -SIGKILL
49 z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Następnie z bieżącego terminala uruchamiamy klienta. Ponieważ serwer pracuje zamyka pętlę zwrotną, czyli odsyła to co otrzymał, więc cokolwiek wprowadzimy zostanie nam natychmiast odesłane przez serwer. $./client pierwszy pierwszy drugi drugi i jeszcze nieco dłuższy łańcuch, i jeszcze nieco dłuższy łańcuch, $ a więc, po wprowadzeniu linii pustej, klient zakończył. Pozostaje nam jeszcze zamknąć serwer. Tak jak sugerowano to wcześniej wykorzystamy w tym celu sygnał SIGKILL, zatem z terminala wykonujemy $ kill -SIGKILL
Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.
Przykład: $ ls more Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi. Tworzenie łącza #include int pipe(int filedes[2]); Przykład: int
Bardziej szczegółowoŁącza nienazwane(potoki)
8. Łącza nienazwane(potoki) Łącze (potok, ang. pipe) jest to urządzenie komunikacyjne pozwalające na przesyłanie informacji w jedną stronę. Jeden proces wysyła dane do łącza za pomocą funkcji write, zaś
Bardziej szczegółowoBiblioteka standardowa - operacje wejścia/wyjścia
Biblioteka standardowa - operacje wejścia/wyjścia Przemysław Gawroński D-10, p. 234 Wykład 6 15 stycznia 2019 (Wykład 6) Biblioteka standardowa - operacje wejścia/wyjścia 15 stycznia 2019 1 / 14 Outline
Bardziej szczegółowo4.2 Sposób korzystania z l acza
4.2 Sposób korzystania z l acza 31 Opis programu: Program procesu potomnego (linie 16 19) jest taki sam, jak w przyk ladzie na listingu 3. W procesie macierzystym nastepuje z kolei przekierowanie standardowego
Bardziej szczegółowoLaboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach
Laboratorium Systemów Operacyjnych Ćwiczenie 4. Operacje na plikach Wykonanie operacji wymaga wskazania pliku, na którym operacja ma zostać wykonana. Plik w systemie LINUX identyfikowany jest przez nazwę,
Bardziej szczegółowoObsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011
Obsługa plików Systemy Operacyjne 2 laboratorium Mateusz Hołenko 25 września 2011 Plan zajęć 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach otwieranie i zamykanie zapis i odczyt
Bardziej szczegółowoKolejki FIFO (łącza nazwane)
Kolejki FIFO (łącza nazwane) Systemy Operacyjne 2 laboratorium Mateusz Hołenko 6 listopada 2011 Plan zajęć 1 Łącza w systemie Linux kolejki FIFO vs. potoki specyfika łączy nazwanych schemat komunikacji
Bardziej szczegółowoĆwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.
Laboratorium Podstaw Informatyki Strona 1 Laboratorium Podstaw Informatyki Kierunek Elektrotechnika Ćwiczenie 4 Obsługa plików Kraków 2010 Laboratorium Podstaw Informatyki Strona 2 Obsługa plików Zanim
Bardziej szczegółowoFunkcje zawarte w bibliotece < io.h >
PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece
Bardziej szczegółowoInstrukcja do laboratorium Systemów Operacyjnych (semestr drugi)
Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) wiczenie trzecie Temat: Potoki i ł cza nazwane w Linuksie. Opracowanie: mgr in ż. Arkadiusz Chrobot Wprowadzenie 1. Komunikacja z wykorzystaniem
Bardziej szczegółowoPliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:
Pliki W celu wykonania jakiejkolwiek operacji na istniejącym pliku, plik ten musi zostać otwarty, natomiast jeśli plik jeszcze nie istnieje, to musi zostać utworzony. Plik może zostać otwarty w trybie:
Bardziej szczegółowoFunkcje zawarte w bibliotece < io.h >
PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece
Bardziej szczegółowoKomunikacja za pomocą potoków. Tomasz Borzyszkowski
Komunikacja za pomocą potoków Tomasz Borzyszkowski Wstęp Sygnały, omówione wcześniej, są użyteczne w sytuacjach błędnych lub innych wyjątkowych stanach programu, jednak nie nadają się do przekazywania
Bardziej szczegółowoObsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013
Laboratorium Podstaw Informatyki Strona 1 Laboratorium Podstaw Informatyki Kierunek Elektrotechnika Obsługa plików Kraków 2013 Laboratorium Podstaw Informatyki Strona 2 Obsługa plików Zanim będziemy mogli
Bardziej szczegółowoInstrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)
Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) Ćwiczenie trzecie (jedne zajęcia) Temat: Potoki i łącza nazwane w Linuksie. Opracowanie: dr in ż. Arkadiusz Chrobot Wprowadzenie 1. Komunikacja
Bardziej szczegółowoProgramowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.
Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni Wykład 6 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Wskaźnik do pliku Dostęp do pliku: zapis, odczyt,
Bardziej szczegółowoObsługa plików Procesy
Obsługa plików Procesy Systemy Operacyjne 2 laboratorium Mateusz Hołenko 15 października 2011 Plan zajęć 1 Obsługa plików 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach 3 Operacje
Bardziej szczegółowoProcesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011
Procesy Systemy Operacyjne 2 laboratorium Mateusz Hołenko 9 października 2011 Plan zajęć 1 Procesy w systemie Linux proces procesy macierzyste i potomne procesy zombie i sieroty 2 Funkcje systemowe pobieranie
Bardziej szczegółowoOperacje na plikach. Informatyka. Standardowe strumienie wejścia i wyjścia
Materiały Operacje na plikach Informatyka Operacje wejścia-wyjścia w C/C++: Podejście proceduralne Podejście obiektowe Standardowe strumienie wejścia i wyjścia stdin - strumień wejściowy (klawiatura) cin
Bardziej szczegółowoMETODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się
Bardziej szczegółowoWskaźniki do funkcji. Wykład 11. Podstawy programowania ( język C ) Wskaźniki do funkcji (1) Wskaźniki do funkcji (2)
Podstawy programowania ( język C ) Wskaźniki do funkcji Wykład 11. Tomasz Marks - Wydział MiNI PW -1- Tomasz Marks - Wydział MiNI PW -2- Wskaźniki do funkcji (1) W języku C funkcje nie są zmiennymi, ale
Bardziej szczegółowoTablice, funkcje - wprowadzenie
Tablice, funkcje - wprowadzenie Przemysław Gawroński D-10, p. 234 Wykład 5 25 marca 2019 (Wykład 5) Tablice, funkcje - wprowadzenie 25 marca 2019 1 / 12 Outline 1 Tablice jednowymiarowe 2 Funkcje (Wykład
Bardziej szczegółowoWstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.
Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy Wykład 12 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji (1) Obsługa łańcuchów znakowych getchar(), putchar()
Bardziej szczegółowoLaboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak
Laboratorium z systemów operacyjnych System plików - funkcje systemowe Anna Wojak 1 Zagadnienia do samodzielnego przygotowania: podstawowe polecenia linux, podstawy programowania w jezyku C, deskryptor
Bardziej szczegółowoPliki. Informacje ogólne. Obsługa plików w języku C
Pliki Informacje ogólne Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych (np. dysku twardym, pendrive, płycie DVD itp.). Może posiadać określone atrybuty, a odwołanie do niego
Bardziej szczegółowoPliki. Informacje ogólne. Obsługa plików w języku C
Pliki Informacje ogólne Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych. Może posiadać określone atrybuty, a odwołanie do niego odbywa się poprzez nazwę. Każdy plik ma skończoną
Bardziej szczegółowoProgramowanie w językach wysokiego poziomu
Programowanie w językach wysokiego poziomu zajęcia nr 2 Elektronika i Telekomunikacja, semestr III rok akademicki 2014/2015 Plan dzisiejszych zajęć Pliki tekstowe 1. Operacje na plikach - wprowadzenie
Bardziej szczegółowoPoniższe funkcje opisane są w 2 i 3 części pomocy systemowej.
Procesy Proces (zwany też zadaniem) jest jednostką aktywną, kontrolowaną przez system operacyjny i związaną z wykonywanym programem. Proces ma przydzielone zasoby typu pamięć (segment kodu, segment danych,
Bardziej szczegółowoJęzyki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.
Typy, operatory, wyrażenia. Wejście i wyjście. Typy, operatory, wyrażenia Zmienna: [] [ '[' ']' ] ['=' ]; Zmienna to fragment pamięci o określonym
Bardziej szczegółowoINFORMATYKA Studia Niestacjonarne Elektrotechnika
INFORMATYKA Studia Niestacjonarne Elektrotechnika Wydział Elektrotechniki i Informatyki dr inż. Michał Łanczont Wydział Elektrotechniki i Informatyki p. E419 tel. 81-538-42-93 m.lanczont@pollub.pl http://lanczont.pollub.pl
Bardziej szczegółowoSystemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot
Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot 15 października 2016 Wstęp W tej instrukcji zawarte są informacje na temat jednych z podstawowych
Bardziej szczegółowoStrumienie i pliki. Programowanie Proceduralne 1
Strumienie i pliki. Programowanie Proceduralne 1 Ogólnie o plikach Plik - ciąg bajtów o skończonej długości Nawa pliku nie stanowi jego części Położenie pliku określone przez ścieżkę dostępu Pliki są opatrzone
Bardziej szczegółowoISO/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
Plik to uporządkowany ciąg danych Dostęp do danych w pliku jest sekwencyjny, tj. istnieje pojęcie elementu aktualnego (tzw. wskaźnika pliku). Możliwy dostęp do danych w pliku jest tylko tam, gdzie wskazuje
Bardziej szczegółowoTemat zajęć: Obsługa łączy komunikacyjnych
Temat zajęć: Obsługa łączy komunikacyjnych Czas realizacji zajęć: 180 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: I. Łącza komunikacyjne Potoki nienazwane, potoki nazwane, przykłady
Bardziej szczegółowoPodstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja
Bardziej szczegółowoGhost in the machine
Operacje na pami eci i odrobina I/O Zak lad Chemii Teoretycznej UJ 8 stycznia 2007 Funkcje operujace Wstep do operacji I/O na plikach 1 Operacje na pami eci 2 Funkcje operujace 3 Wst Funkcje operujace
Bardziej szczegółowoISO/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
Plik to uporządkowany ciąg danych Dostęp do danych w pliku jest sekwencyjny, tj. istnieje pojęcie elementu aktualnego (tzw. wskaźnika pliku). Możliwy dostęp do danych w pliku jest tylko tam, gdzie wskazuje
Bardziej szczegółowo2 Przygotował: mgr inż. Maciej Lasota
Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania
Bardziej szczegółowoProgramowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.
Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni Wykład 6 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411b Plan wykładu Operacje wejścia-wyjścia Dostęp do plików Struktury
Bardziej szczegółowoISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje
Funkcje (podprogramy) Mianem funkcji określa się fragment kodu, który może być wykonywany wielokrotnie z różnych miejsc programu. Ogólny zapis: typ nazwa(argumenty) ciało funkcji typ określa typ danych
Bardziej szczegółowoUŻYCIE I ZARZĄDZANIE WĄTKAMI
Proces jako pewna instancja programu, w trakcie wykonania, ze swej natury w każdym systemie operacyjnym wyróżniają: prawa własności zasobu a jednym z fundamentalnych zadań systemu jest ochrona przed jednoczesnym
Bardziej szczegółowoSYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy)
Procesy i shell. Polecenia ps, sleep, exit, jobs, bg, fg, top, kill, bash, tcsh, which, type, whereis, touch. Metaznak & i >>. Dowiązania miękkie i twarde. Proces jest programem, który jest wykonywany
Bardziej szczegółowoAplikacja Sieciowa wątki po stronie klienta
Aplikacja Sieciowa wątki po stronie klienta Na ostatnich zajęciach zajmowaliśmy się komunikacją pomiędzy klientem a serwerem. Wynikiem naszej pracy był program klienta, który za pomocą serwera mógł się
Bardziej szczegółowoPliki. Operacje na plikach w Pascalu
Pliki. Operacje na plikach w Pascalu ścieżka zapisu, pliki elementowe, tekstowe, operacja plikowa, etapy, assign, zmienna plikowa, skojarzenie, tryby otwarcia, reset, rewrite, append, read, write, buforowanie
Bardziej szczegółowoPliki wykład 2. Dorota Pylak
Pliki wykład 2 Dorota Pylak Struktura programu działającego na plikach 1) Dyrektywa preprocesora #include //zapewnia dostęp do strumieni ifstream i ofstream 2) deklaracja zmiennej (strumienia)
Bardziej szczegółowoOPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)
OPERACJE WEJŚCIA / WYJŚCIA Funkcja: printf() biblioteka: wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout) int printf ( tekst_sterujący, argument_1, argument_2,... ) ;
Bardziej szczegółowoUŻYCIE I ZARZĄDZANIE WĄTKAMI
Proces jako pewna instancja programu, w trakcie wykonania, ze swej natury w każdym systemie operacyjnym wyróżniają: prawa własności zasobu a jednym z fundamentalnych zadań systemu jest ochrona przed jednoczesnym
Bardziej szczegółowo1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
Bardziej szczegółowoStałe i zmienne znakowe. Stała znakowa: znak
Stałe i zmienne znakowe. Stała znakowa: znak Na przykład: a, 1, 0 c Każdy znak jest reprezentowany w pamięci przez swój kod. Kody alfanumerycznych znaków ASCII to liczby z przedziału [32, 127]. Liczby
Bardziej szczegółowoProcesy i potoki. S. Samolej: Procesy
Procesy i potoki dr inż. Sławomir Samolej Katedra Informatyki i Automatyki Politechnika Rzeszowska Program przedmiotu oparto w części na materiałach opublikowanych na: http://wazniak.mimuw.edu.pl/ oraz
Bardziej szczegółowoProgram wykonujący operację na plikach powinien zachować schemat działania zapewniający poprawną pracę:
Rozdział 1 Obsługa plików W językach C pliki powiązane są ze strumieniami i pracuje się na nich podobnie jak na innych strumieniach. W języku C do operacji na plikach służą funkcje z biblioteki stdio.h,
Bardziej szczegółowoPowłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh.
Powłoka I Popularne implementacje W stylu sh (powłoki zdefiniowanej w POSIX) bash (najpopularniejsza) zsh ksh mksh W stylu csh csh tcsh 12 października 2018 1 / 16 Powłoka II Zachęta Komunikuje się z użytkownikiem
Bardziej szczegółowoPodstawy programowania w języku C++
Podstawy programowania w języku C++ Część jedenasta Reprezentacja i przetwarzanie plików Konwencja języka C Autor Roman Simiński Kontakt roman.siminski@us.edu.pl www.us.edu.pl/~siminski Niniejsze opracowanie
Bardziej szczegółowo7 Przygotował: mgr inż. Maciej Lasota
Laboratorium nr 7 1/5 Język C Instrukcja laboratoryjna Temat: Operacje na plikach. 7 Przygotował: mgr inż. Maciej Lasota 1) Pliki. Plik (ang. file), jest to nazwany ciąg danych (inaczej zbiór danych),
Bardziej szczegółowo4. Komunikacja pomiędzy procesami przez łącza nienazwane i nazwane
Jędrzej Ułasiewicz Łącza nienazwane, nazwane, funkcja select 1 4. Komunikacja pomiędzy procesami przez łącza nienazwane i nazwane Łącza nienazwane (ang. Unnamed Pipes) i nazwane (ang. Named Pipes) - jedna
Bardziej szczegółowoPlik jest reprezentowany przez strumień znaków (bajtów) o zmiennej długości. Koniec strumienia identyfikowany jest znacznikiem końca pliku EOF.
Pliki w C++ Plik jest reprezentowany przez strumień znaków (bajtów) o zmiennej długości. Koniec strumienia identyfikowany jest znacznikiem końca pliku EOF. Z każdym strumieniem związany jest wskaźnik bieżącej
Bardziej szczegółowoPodstawy programowania skrót z wykładów:
Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace
Bardziej szczegółowoFormatowane (tekstowe) wejście/wyjście. Binarne wejście/wyjście.
Formatowane (tekstowe) wejście/wyjście. Binarne wejście/wyjście. wer. 10 z drobnymi modyfikacjami! Wojciech Myszka 2018-03-27 09:06:38 +0200 Część I Formatowane (tekstowe) wejście/wyjście Otwarcie pliku
Bardziej szczegółowoTemat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.
Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych. 1. Rodzaje pamięci używanej w programach Pamięć komputera, dostępna dla programu,
Bardziej szczegółowoJ. Ułasiewicz Łącza nienazwane, nazwane, select 1
J. Ułasiewicz Łącza nienazwane, nazwane, select 1 4. Komunikacja pomiędzy procesami przez łącza nienazwane i nazwane Łącza nienazwane (ang. Unnamed Pipes) i nazwane (ang. Unnamed Pipes) - jedna z historycznie
Bardziej szczegółowoUruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias
7 październik 2008 Uruchomienie, monitorowanie procesu, potoki, aliasy S laj d 1 Uruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias 7 październik 2008 Uruchomienie, monitorowanie
Bardziej szczegółowoPodstawy programowania w języku C++
Podstawy programowania w języku C++ Część jedenasta Przetwarzanie plików amorficznych Konwencja języka C Autor Roman Simiński Kontakt roman.siminski@us.edu.pl www.us.edu.pl/~siminski Niniejsze opracowanie
Bardziej szczegółowoPliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego
Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego 1 /24 Pisanie pojedynczych znaków z klawiatury do pliku #include void main(void) { FILE *fptr; // wkaznik do pliku, tzw. uchwyt
Bardziej szczegółowoStruktury. Przykład W8_1
Struktury Struktury pozwalają na grupowanie zmiennych różnych typów pod wspólną nazwą. To istotnie ułatwia organizacje danych, które okazują się w jednym miejscu kodu programu. To jest bardzo ważne dla
Bardziej szczegółowoArgumenty wywołania programu, operacje na plikach
Temat zajęć: Argumenty wywołania programu, operacje na plikach Autor: mgr inż. Sławomir Samolej Zagadnienie 1. (Zmienne statyczne) W języku C można decydować o sposobie przechowywania zmiennych. Decydują
Bardziej szczegółowoPodstawy programowania, Poniedziałek , 8-10 Projekt, część 1
Podstawy programowania, Poniedziałek 30.05.2016, 8-10 Projekt, część 1 1. Zadanie Projekt polega na stworzeniu logicznej gry komputerowej działającej w trybie tekstowym o nazwie Minefield. 2. Cele Celem
Bardziej szczegółowoProgramowanie Proceduralne
Programowanie Proceduralne Pliki Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 12 Operacje plikowe Plik - dokument lub inny zbiór danych zapisany na dysku, oznaczony unikatowa
Bardziej szczegółowoWskaźniki w C. Anna Gogolińska
Wskaźniki w C Anna Gogolińska Zmienne Zmienną w C można traktować jako obszar w pamięci etykietowany nazwą zmiennej i zawierający jej wartość. Przykład: kod graficznie int a; a a = 3; a 3 Wskaźniki Wskaźnik
Bardziej szczegółowoCzęść 4 życie programu
1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część
Bardziej szczegółowoJęzyki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński
Języki programowania Część siódma Przetwarzanie plików amorficznych Konwencja języka C Autorzy Tomasz Xięski Roman Simiński Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie
Bardziej szczegółowo1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.
1. Pierwszy program // mój pierwszy program w C++ #include using namespace std; cout
Bardziej szczegółowoKOLEJKI KOMUNIKATÓW IPC
z przedmiotu, prowadzonych na Wydziale BMiI, Akademii Techniczno-Humanistycznej w Bielsku-Białej. Współbieżność procesów (czy wątków) wiąże się często z potrzebą okresowej (asynchronicznej) wymiany komunikatów.
Bardziej szczegółowoNarzędzia informatyczne w językoznawstwie
Narzędzia informatyczne w językoznawstwie Wiersz poleceń - Potoki i pliki wsadowe Marcin Junczys-Dowmunt junczys@amu.edu.pl Zakład Logiki Stosowanej http://www.logic.amu.edu.pl 22. października 2008 Marcin
Bardziej szczegółowoPodstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++
Podstawy Informatyki Inżynieria Ciepła, I rok Wykład 10 Kurs C++ Historia Lata 70-te XX w język C (do pisania systemów operacyjnych) "The C programming language" B. Kernighan, D. Ritchie pierwszy standard
Bardziej szczegółowo۰ Elementem jednostkowym takiego pliku jest bajt. ۰ Format pliku binarnego: [bajty pliku][eof]
1 Plik jest wydzielonym fragmentem pamięci (najczęściej dyskowej) posiadającym nazwę. Z punktu widzenia C plik jest ciągiem bajtów, z których każdy może zostać oddzielnie odczytany. Zgodnie ze standardem
Bardziej szczegółowoPROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec
PROE wykład 3 klasa string, przeciążanie funkcji, operatory dr inż. Jacek Naruniec Przypomnienie z ostatnich wykładów Konstruktory/destruktory i kolejność ich wywołania w złożonej klasie. Referencja Obiekty
Bardziej szczegółowoLaboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski
Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski 7 kwietnia 2014 1. Wprowadzenie Pierwsza część instrukcji zawiera informacje
Bardziej szczegółowoStałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane
Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane Stałe Oprócz zmiennych w programie mamy też stałe, które jak sama nazwa mówi, zachowują swoją wartość przez cały czas działania programu. Można
Bardziej szczegółowoProgramowanie w językach
Programowanie w językach wysokiego poziomu Obsługa plików za pomocą strumieni Elektronika i Telekomunikacja, semestr III rok akademicki 2013/2014 dr inż. Paweł Myszkowski Plan zajęć a) otwieranie i zamykanie
Bardziej szczegółowo#include <stdio.h> int main( ) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }
OPERACJE WEJŚCIA / WYJŚCIA Funkcja: printf() biblioteka: wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout) int printf ( tekst_sterujący, argument_1, argument_2,... ) ;
Bardziej szczegółowoLekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()
Paweł Gmys PHP strona 1 Lekcja 10 Uprawnienia Aby skrypt PHP mógł odwołać się do pliku, musi mieć odpowiednie uprawnienia. Szczegóły są zależne od serwera. Najczęściej chyba skrypt ma uprawnienia takie,
Bardziej szczegółowoTemat zajęć: Filtry, strumienie standardowe oraz przetwarzanie potokowe. stderr
Temat zajęć: Filtry, strumienie standardowe oraz przetwarzanie potokowe Czas realizacji zajęć: 180 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: Strumienie standardowe i ich przekierowywanie,
Bardziej szczegółowoPodstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1 Pętle Pętla jest konstrukcją sterującą stosowaną w celu wielokrotnego wykonania tego samego zestawu instrukcji jednokrotne
Bardziej szczegółowoTemat zajęć: Obsługa systemu plików.
Temat zajęć: Obsługa systemu plików. Czas realizacji zajęć: 90 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: I. Operacje na plikach zwykłych. Tworzenie i otwieranie plików, deskryptory
Bardziej szczegółowoPobieranie argumentów wiersza polecenia
Pobieranie argumentów wiersza polecenia 2. Argumenty wiersza polecenia Lista argumentów Lista argumentów zawiera cały wiersz poleceń, łącznie z nazwą programu i wszystkimi dostarczonymi argumentami. Przykłady:
Bardziej szczegółowo#include <stdio.h> void main(void) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }
OPERACJE WEJŚCIA / WYJŚCIA Funkcja: printf() biblioteka: wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout) int printf ( tekst_sterujący, argument_1, argument_2,... ) ;
Bardziej szczegółowoFunkcja (podprogram) void
Funkcje Co to jest funkcja? Budowa funkcji Deklaracja, definicja i wywołanie funkcji Przykłady funkcji definiowanych przez programistę Przekazywanie argumentów do funkcji Tablica jako argument funkcji
Bardziej szczegółowoInstrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)
Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) Ćwiczenie drugie (jedne zajęcia) Temat: Procesy i sygnały w Linuksie. Opracowanie: mgr in ż. Arkadiusz Chrobot Wprowadzenie 1. Budowa procesu
Bardziej szczegółowo1. Wprowadzanie danych z klawiatury funkcja scanf
1. Wprowadzanie danych z klawiatury funkcja scanf Deklaracja int scanf ( const char *format, wskaźnik, wskaźnik,... ) ; Biblioteka Działanie stdio.h Funkcja scanf wczytuje kolejne pola (ciągi znaków),
Bardziej szczegółowoI - Microsoft Visual Studio C++
I - Microsoft Visual Studio C++ 1. Nowy projekt z Menu wybieramy File -> New -> Projekt -> Win32 Console Application w okienku Name: podajemy nazwę projektu w polu Location: wybieramy miejsce zapisu i
Bardziej szczegółowoJęzyki programowania. Karolina Mikulska-Rumińska Pokój 573, tel Konsultacje wtorek 9-10.
Języki programowania Karolina Mikulska-Rumińska E-mail: karolamik@fizyka.umk.pl Pokój 573, tel. 3346 Konsultacje wtorek 9-10. Pliki Dwa rodzaje plików: Tekstowe, Binarne Aby otworzyć plik należy najpierw
Bardziej szczegółowo1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
Bardziej szczegółowoĆwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:
Ćwiczenie nr 6 Temat: Operacje na łańcuchach znaków. Zagadnienia: Zasady pracy z łańcuchami tekstowymi (tablice wartości typu char). funkcje standardowe operacji na łańcuchach, funkcje I/O dla operacji
Bardziej szczegółowo1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość
1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 2. Poprawna definicja wskażnika b to: a) float *a, **b = &a; b) float
Bardziej szczegółowoLinux Kernel III. Character devices
Linux Kernel III Character devices Urządzenia systemu Linux (I) Character device Block device Network device Do urządzenia piszemy jak do pliku, Dozwolone działania: open, close, read, write, Np. /dev/tty1.
Bardziej szczegółowoWstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania
Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania Przemysław Kobylański Wprowadzenie Każdy program w C musi zawierać przynajmniej funkcję o nazwie main(): Aby możliwe
Bardziej szczegółowoUwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)
Uwagi dotyczące notacji kodu! Wyrazy drukiem prostym -- słowami języka VBA. Wyrazy drukiem pochyłym -- inne fragmenty kodu. Wyrazy w [nawiasach kwadratowych] opcjonalne fragmenty kodu (mogą być, ale nie
Bardziej szczegółowoJęzyki i metodyka programowania. Wprowadzenie do języka C
Literatura: Brian W. Kernighan, Dennis M. Ritchie Język Ansi C, Wydawnictwa Naukowo - Techniczne, 2007 http://cm.bell-labs.com/cm/cs/cbook/index.html Scott E. Gimpel, Clovis L. Tondo Język Ansi C. Ćwiczenia
Bardziej szczegółowoProgramowanie Współbieżne. W Linuxie/Unixie
Programowanie Współbieżne W Linuxie/Unixie Komunikacja p r o c e s u ż y t k o w n i k a 1 p r o c e s u ż y t k o w n i k a 2 J ą d r o s y s t e m u Komunikacja p r o c e s u ż y t k o w n i k a 1 p
Bardziej szczegółowoWykład PASCAL - Pliki tekstowe
Podstawy programowania Wykład PASCAL - Pliki tekstowe 1 dr Artur Bartoszewski - Podstawy prograowania, sem. 1- WYKŁAD Rodzaje plików Dane przechowywane w pliku mogą mieć reprezentację binarną (taką samą,
Bardziej szczegółowo