Komunikacja za pomocą potoków. Tomasz Borzyszkowski



Podobne dokumenty
Kolejki FIFO (łącza nazwane)

Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi)

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

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

Łącza nienazwane(potoki)

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

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

Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy)

Klient-Serwer Komunikacja przy pomocy gniazd

4.2 Sposób korzystania z l acza

System plików. Warstwowy model systemu plików

Zwielokrotnianie wejścia wyjścia

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

Mechanizmy pracy równoległej. Jarosław Kuchta

Jak wiemy, wszystkich danych nie zmieścimy w pamięci. A nawet jeśli zmieścimy, to pozostaną tam tylko do najbliższego wyłączenia zasilania.

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

Operatory zmiany sposobu przypisania standardowych strumieni >,<,>> Jeżeli pierwsze polecenie powiodło się to wykona drugie

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh.

Dodatek B. Zasady komunikacji z otoczeniem w typowych systemach komputerowych

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

Obsługa sygnałów. Tomasz Borzyszkowski

Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.

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

Pliki. Operacje na plikach w Pascalu

1 second UPS. Poziom trudności: łatwy. Wersja dokumentacji: 1.3. Aktualizacja: Beckhoff Automation Sp. z o. o.

Futex (Fast Userspace Mutex) Łukasz Białek

Komunikacja między sterownikami przez protokół ADS

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

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Kopiowanie, przenoszenie plików i folderów

Akademia Techniczno-Humanistyczna w Bielsku-Białej

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wykład PASCAL - Pliki tekstowe

Od uczestników szkolenia wymagana jest umiejętność programowania w języku C oraz podstawowa znajomość obsługi systemu Linux.

5. Model komunikujących się procesów, komunikaty

Procesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011

SYSTEMY CZASU RZECZYWISTEGO - VxWorks

UWAGA!!! Przed przystąpieniem do zamknięcia roku proszę zrobić kopie bezpieczeństwa

Ćwiczenie: JavaScript Cookies (3x45 minut)

SYSTEMY OPERACYJNE WYKLAD 6 - procesy

Logiczny model komputera i działanie procesora. Część 1.

Systemy operacyjne na platformach mobilnych 2 Podstawy obsługi powłoki Bash

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

INFRA. System Connector. Opis wdrożenia systemu

Temat zajęć: Tworzenie i obsługa wątków.

Kontrola dostępu przy użyciu sterownika Sterbox.

Stan globalny. Krzysztof Banaś Systemy rozproszone 1

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

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

TRX API opis funkcji interfejsu

CZĘŚĆ A PIERWSZE KROKI Z KOMPUTEREM

1 Przygotował: mgr inż. Maciej Lasota

System plików warstwa logiczna

Wstęp. Skąd pobrać program do obsługi FTP? Logowanie

Model procesu w systemie Linux. Tomasz Borzyszkowski

Kontrola sesji w PHP HTTP jest protokołem bezstanowym (ang. stateless) nie utrzymuje stanu między dwoma transakcjami. Kontrola sesji służy do

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

Projektowanie oprogramowania systemów KOMUNIKACJA MIĘDZYPROCESOWA

Programowanie Współbieżne. W Linuxie/Unixie

Kurs systemu Unix wykład wstępny. Kurs systemu Unix 1

Temat zajęć: Obsługa procesów w systemie.

76.Struktura oprogramowania rozproszonego.

System operacyjny MACH

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Przychodnia 0. Stwórz projekt aplikacja konsolowa lub WPF (przemyśl wybór, bo zmiana może być czasochłonna). 1. Stwórz abstrakcyjną klasę Osoba.

Systemy Operacyjne - Operacje na plikach

ang. file) Pojęcie pliku (ang( Typy plików Atrybuty pliku Fragmentacja wewnętrzna w systemie plików Struktura pliku

Strumienie, pliki. Sortowanie. Wyjątki.

4. Procesy pojęcia podstawowe

JĘZYK SHELL JEST PEŁNYM JĘZYKIEM PROGRAMOWANIA

Wstęp do programowania 2

Instytut Teleinformatyki

dr inż. Jarosław Forenc

W otwartym oknie w zakładce Ogólne znajdujemy opcje Podpis. Po zaznaczeniu pola wyboru, w edytorze możemy zredagować dołączaną treść.

Linux: Procesy. Systemy Operacyjne. Mateusz Hołenko. 26 marca 2013

SEGMENT TCP CZ. II. Suma kontrolna (ang. Checksum) liczona dla danych jak i nagłówka, weryfikowana po stronie odbiorczej

Zmienne powłoki. Wywołanie wartości następuje poprzez umieszczenie przed nazwą zmiennej znaku dolara ($ZMIENNA), np. ZMIENNA=wartosc.

Przedrostkowa i przyrostkowa inkrementacja i dekrementacja

Wysyłka do systemu e-deklaracje

BAZY DANYCH. Transakcje. opracowanie: Michał Lech

Programowanie Równoległe i Rozproszone

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

Aplikacja Sieciowa wątki po stronie klienta

Program dla praktyki lekarskiej

Języki skryptowe - PHP. PHP i bazy danych. Paweł Kasprowski. pawel@kasprowski.pl. vl07

Paweł Rajba

Działanie systemu operacyjnego

Transport. część 2: protokół TCP. Sieci komputerowe. Wykład 6. Marcin Bieńkowski

Programowanie w Logice

1 Podstawy c++ w pigułce.

Działanie systemu operacyjnego

Laboratorium Komputerowe Systemy Pomiarowe

Administracja i programowanie pod Microsoft SQL Server 2000

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Aktualizacja map TT Europa. Aktualizacja map TT Europa w programie mapfactor Navigator w urządzeniach SmartGPS - instrukcja

ROZPROSZONE SYSTEMY OPERACYJNE. Niezawodne usługi w rozwiązaniach SSI dokumentacja projektu. Karol Ostrowski 16 czerwca 2005

Wykład 8: klasy cz. 4

Podręcznik użytkownika

Transkrypt:

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 dużej ilości informacji z jednego procesu do drugiego. Jednym z możliwych sposobów rozwiązania tego problemu dla procesów jest korzystanie ze wspólnych plików. Jednak może to okazać się nieefektywne oraz może prowadzić do problemów dostępu do wspólnych zasobów. Systemy Unixowe dostarczają konstrukcji nazywanej potokiem (ang. pipe). Potok jest używany najczęściej jako jednokierunkowy kanał komunikacyjny, łączący ze sobą powiązane procesy, stanowiąc zarazem uogólnienie pojęcia pliku w systemie Unix. Na jednym końcu potoku proces wysyła dane, zapisując je do potoku za pomocą systemowej funkcji write, natomiast na drugim końcu (inny) proces może je odczytywać używając funkcji read. Z mechanizmu potoków korzystaliśmy już w sposób niejawny, składając polecenia powłoki postaci: $ who grep kazio 2

Pogramowanie z potokami Wewnątrz programu potok jest tworzony za pomocą funkcji systemowej o nazwie pipe. W przypadku pomyślnego zakończenia zwraca dwa deskryptory plików, jeden do zapisu do potoku i drugi do odczytu z potoku. Nagłówek funkcji znajduje się w pliku <unistd.h> i ma następującą postać: int pipe(int filedes[2]); filedes to tablica dwóch liczb całkowitych, pierwsza filedes[0] to deskryptor odczytu z potoku, druga filedes[1] deskryptor zapisu do potoku. Funkcja może zwrócić -1, gdy nie można otworzyć nowych deskryptorów plików. Zobacz: potok1.c Komunikację przedstawioną w przykładzie można przedstawić za pomocą następującego schematu: read() p[0] write() p[1] 3

Pogramowanie z potokami cd W poprzednim przykładzie komunikaty zostały odczytane w takiej kolejności, w jakiej zostały zapisane. Potok traktuje dane jak kolejkę FIFO (= pierwszy na wejściu, pierwszy na wyjściu, ang. First In, First Out). Przedstawiony przykład prezentował komunikację potoku samego ze sobą. Prawdziwa wartość potoku staje się widoczna dopiero, gdy jest on użyty do komunikacji między różnymi procesami. Zobacz: potok2.c Schemat komunikacji przedstawionej w przykładzie: read() p[0] p[0] read() write() proces potomny p[1] p[1] write() proces rodzicielski 4

Pogramowanie z potokami cd II Procesy z poprzedniego przykładu mają otwarte deskryptory pliku, pozwalające odczytywać z i zapisywać do potoku. Każdy z procesów może zapisywać do deskryptora p[1] i odczytywać z deskryptora pliku p[0]. Pojawia się tu problem: jeżeli oba procesy zaczną pisać do i czytać z potoku, może powstać zamieszanie. Dlatego, jeżeli proces tylko pisze, to powinien zamknąć kanał odczytu i na odwrót. Zobacz: potok3.c Schemat komunikacji przedstawionej w przykładzie: read() p[0] read() write() proces potomny p[1] write() proces rodzicielski 5

Wielkość potoku Zobacz: rozmiar.c Potoki mają ograniczoną pojemność, tj. w potoku może znajdować się tylko pewna ilość bajtów. Minimalna ilość jest określona w standardzie POSIX jako 512 bajtów. W rzeczywistości (zwykle) systemy pozwalają na znacznie większe wartości. Znajomość maksymalnej wielkości potoku jest istotna, ponieważ wpływa na operacje zapisu i odczytu. Jeżeli zapisujemy do potoku, w którym jest dostateczna ilość miejsca, dane są wysyłane do potoku, a wywołanie funkcji write zwraca niezwłocznie. Jeżeli jednak wykonujemy zapis do potoku, który przepełnia potok, wykonanie procesu zostaje zawieszone, dopóty inny proces nie zrobi miejsca, odczytując dane z potoku. Jeżeli proces próbuje za pomocą pojedynczego write zapisać więcej danych, niż potok może otrzymać, to jądro zapisze do potoku tyle danych ile będzie mogło, następnie zawiesi wykonanie procesu, aż dostępne stanie się miejsce dla reszty danych. Zwykle zapis do potoku wykonuje się niepodzielnie. W pow. przypadku wiele procesów może pomieszać swoje niepodzielne dane w potoku. 6

Zamykanie potoków Co się dzieje, gdy deskryptor pliku, który reprezentuje jeden koniec potoku zostanie zamknięty? Możliwe są dwa przypadki: Zamknięcie deskryptora pliku do zapisu. Jeżeli istnieją inne procesy, które mają potok otwarty do zapisu, nic się nie dzieje. Jeżeli jednak nie ma więcej procesów z otwartym tym potokiem do zapisu, a potok jest pusty, każdy proces próbujący odczytać dane z potoku wraca bez danych. Procesy, które w uśpieniu czekały na odczyt, zostaną obudzone, a ich funkcje read zwrócą zero, tj. skutek dla procesów czytających przypomina osiągnięcie końca zwykłego pliku. Zamknięcie deskryptora pliku do odczytu. Jeśli istnieją inne procesy, mające potok otwarty do odczytu, to nic się nie zdarzy. Jeśli nie istnieją, to do wszystkich procesów czekających na zapis do potoku będzie przez jądro wysłany sygnał SIGPIPE. Jeśli sygnał nie zostanie przechwycony, proces zakończy się. Jeśli sygnał zostanie przechwycony, po jego obsłudze, write zwróci -1, a zmienna errno będzie zawierać EPIPE. Do procesów piszących do potoku później też wysyłany jest ten sygnał. 7

Nieblokujące odczyty i zapisy Poprzednie przykłady pokazały, że przy używaniu potoków zarówno odczyt, jak i zapis, mogą być zablokowane. Czasami nie jest to pożądane. Np. można chcieć, żeby program wykonał procedurę obsługi błędu lub przeglądał kilka potoków, aż otrzyma dane z jednego z nich. Jednym ze sposobów realizacji pow. zadań, jest następujące wywołanie funkcji fcntl: fcntl(filedes, F_SETFL, O_NONBLOCK); Jeżeli filedes jest dekryptorem potoku do zapisu, to następne wywołania funkcji write nie będą blokowane, nawet jeśli potok jest pełny. W zamian zwracają -1 i ustawiają errno na EAGAIN. Jeżeli filedes jest dekryptorem pustego potoku do odczytu, to następne wywołania funkcji read nie będą blokowane, zwrócą wartości jak w przypadku write. Zobacz: nonblock.c 8

Obsługa wielu potoków Zobacz: select.c Przedstawiony mechanizm nieblokujących odczytów i zapisów jest dobry dla małych aplikacji. Operowanie jednocześnie na wielu potokach znacznie upraszcza użycie funkcji select. Niech proces rodzicielski działa jako proces serwera z dowolną liczbą komunikujących się z nim procesów klienta (potomnych). Serwer musi poradzić sobie z sytuacją, w której informacja nadchodzi więcej niż jednym potokiem. Jeżeli nic nie nadchodzi, to proces serwera powinien się zablokować i czekać aż coś nadejdzie, ale bez ciągłego odpytywania. Gdy informacja nadchodzi więcej niż jednym potokiem, serwer musi wiedzieć, którymi potokami, by odczytać dane w prawidłowej kolejności. Zachowanie podobne do przedstawionego powyżej zapewnia funkcja select. Może być ona używana nie tylko do potoków ale także do zwykłych plików, terminali, plików FIFO i gniazd. Nie będziemy szczegółowo opisywać poszczególnych parametrów funkcji select. W zamian zaprezentujemy przykład jej zastosowania do potoków. 9

Funkcja exec i potoki Pomiędzy dwoma programami na poziomie powłoki może być ustawiony potok, np.: $ ls wc Jak realizuje się takie potoki? Po pierwsze, powłoka wykorzystuje fakt, że otwarte deskryptory plików przechodzą otwarte przez wywołania funkcji exec. Oznacza to, że dwa deskryptory plików dla potoków otwarte przed kombinacją fork/exec pozostaną otwarte, kiedy proces potomny rozpocznie wykonywanie nowego programu. Po drugie, przed wywołaniem exec, powłoka łączy standardowe wyjście ls z końcem potoku przeznaczonym do zapisu i standardowe wejście wc z końcem do odczytu. Może to być zrobione za pomocą funkcji fcntl lub dup2. W następującym przykładzie wykorzystaliśmy ten mechanizm w funkcji join łączącej dwa programy za pomocą potoku. Zobacz: join.c 10

Potoki nazwane = pliki FIFO Potoki są eleganckim i silnym mechanizmem komunikacji między procesami, jednak posiadają pewne wady: Potok może być używany do łączenia procesów, mających wspólnych przodków. Staje się to uciążliwe, gdy chcemy napisać prawdziwy proces serwera, na stałe działający w systemie. Potoki nie mogą być trwałe. Muszą być tworzone za każdym razem, gdy są potrzebne, i usuwane, gdy kończy się korzystający z nich proces. Problemy te rozwiązuje mechanizm komunikacji nazwany plikiem FIFO lub nazwanym potokiem. FIFO działa jak potok ale w odróżnieniu od potoków jest trwały i posiada nazwę i uprawnienia jak plik. Jednocześnie przy zapisie i odczycie wykazuje własności potoku. Plik FIFO tworzymy poleceniem mkfifo(). W starszych wersjach Unixa służyło do tego polecenie mknod(). Szczegóły implementacji zawarte w przykładowych programach: Zobacz: sendfifo.c rcvfifo.c 11