DZWONEK

Są tacy, którzy czytają te wiadomości przed tobą.
Subskrybuj, aby otrzymywać świeże artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać Dzwon
Bez spamu

Skrót IPC oznacza komunikacja międzyprocesowa, to znaczy interakcja procesów. Zwykle odnosi się to do przesyłania różnego rodzaju komunikatów między procesami w dowolnym systemie operacyjnym. W tym przypadku można zastosować różne formy synchronizacji, wymagane przez współczesne rodzaje interakcji, przeprowadzane na przykład przez pamięć współdzieloną.

W trakcie opracowywania rodziny systemów operacyjnych Unix w ciągu ostatnich 30 lat metody przesyłania wiadomości ewoluowały w następujący sposób:

■ Kanały (potoki - rozdział 4) były pierwszą powszechnie stosowaną formą interakcji procesu dostępną dla programów i użytkownika (z interpretera poleceń). Główną wadą kanałów jest niemożność korzystania z nich między procesami, które nie mają wspólnego rodzica (przodka), ale ta wada została wyeliminowana wraz z pojawieniem się nazwanych potoków (nazwanych potoków) lub kanałów FIFO (rozdział 4).

■ Kolejki komunikatów Systemu V (Rozdział 4) zostały dodane do rdzeni Systemu V na początku lat 80. Można ich używać do przesyłania komunikatów między procesami w tym samym węźle, niezależnie od tego, czy procesy te są powiązane. Pomimo przedrostka „System V”, większość współczesnych wersji Uniksa, w tym te niepochodzące z Systemu V, obsługuje te kolejki.

UWAGA

W przypadku procesów uniksowych termin „pokrewieństwo” oznacza, że \u200b\u200bprocesy mają wspólnego przodka. Rozumie się, że procesy, które są krewne, zostały utworzone przez ten proces przodka przy użyciu jednego lub więcej widelców. Najprostszym przykładem byłoby dwukrotne wywołanie rozwidlenia dla jakiegoś procesu, co doprowadzi do utworzenia dwóch procesów spawnowanych. Następnie możemy porozmawiać o związku tych procesów ze sobą. Oczywiście każdy wygenerowany proces jest spokrewniony z tym, który go wygenerował. Rodzic może zadbać o możliwość interakcji z odradzanym procesem (poprzez utworzenie potoku lub kolejki komunikatów) przed wywołaniem rozwidlenia, a ten obiekt IPC zostanie odziedziczony przez odradzany proces. Aby uzyskać więcej informacji na temat dziedziczenia obiektów IPC, zobacz Tabela. 1.4 Należy również zauważyć, że wszystkie procesy uniksowe są teoretycznie potomkami procesu init, który uruchamia wszystko, co niezbędne podczas procesu rozruchu (bootstrapping). Z praktycznego punktu widzenia lepiej policzyć pokrewieństwo procesów z powłoki logowania i wszystkich procesów przez nią utworzonych. Rozdział 9 opisuje bardziej szczegółowo sesje i powiązane relacje procesów.

UWAGA

Takie notatki zostaną wykorzystane przez nas w celu wyjaśnienia funkcji związanych z wdrażaniem, zapewnienia tła historycznego i przydatnych wskazówek.

■ Kolejki komunikatów Posix (kolejki komunikatów Posix - Rozdział 5) zostały dodane do standardu Posix (1003.1b-1993, który omówiono bardziej szczegółowo w Rozdziale 1.7). Mogą być używane do interakcji powiązanych i niepowiązanych procesów w dowolnym węźle.

■ Zdalne wywołania procedur (RPC, część 5) pojawiły się w latach 80. jako środek do wywoływania funkcji w jednym systemie (serwerze) przez program działający w innym systemie (kliencie). To narzędzie zostało opracowane jako alternatywa dla uproszczenia programowania sieciowego. Ponieważ informacje są zwykle przesyłane między klientem a serwerem (przekazywane są argumenty za wywołaniem funkcji i zwracane wartości), a ponieważ zdalne wywołanie procedury może być używane między klientem a serwerem w tym samym węźle, RPC można również uznać za formę przesyłania wiadomości.

Interesujące jest również spojrzenie na ewolucję różnych form synchronizacji podczas opracowywania Uniksa:

■ Pierwsze programy, które wymagały synchronizacji (najczęściej w celu zapobieżenia jednoczesnej zmianie zawartości pliku przez wiele procesów) korzystały z funkcji systemu plików, z których niektóre opisano w sekcji 9.8,

■ Blokowanie rekordów (rozdział 9) zostało dodane do jądra Uniksa na początku lat 80. i znormalizowane w Posix.1 w 1988 r.

■ Dodano semafory Systemu V (semafory Systemu V - rozdział 11) wraz z możliwością współdzielenia pamięci (pamięć współdzielona Systemu V - rozdział 14) i jednocześnie z kolejkami komunikatów Systemu V (wczesne lata 80.). Te IPC są obsługiwane przez większość nowoczesnych wersji Uniksa.

■ Semafory Posix (semafory Posix - rozdział 10) i pamięć współdzielona Posix (pamięć współdzielona Posix - rozdział 13) zostały również dodane do standardu Posix (1003.1b-1993, o którym wcześniej wspomniano w związku z kolejkami komunikatów Posix).

■ Wzajemne wyjątki i zmienne warunkowe (mutex, zmienna warunkowa - rozdział 7) to dwie formy synchronizacji zdefiniowane w standardzie wątków oprogramowania Posix (wątki Posix, Pthreads - 1003.1s-1995). Chociaż są zwykle używane do synchronizacji między wątkami, mogą być również używane do organizowania interakcji procesów.

■ Blokady odczytu i zapisu (rozdział 8) są dodatkową formą synchronizacji. Nie jest jeszcze uwzględniony w standardzie Posix, ale prawdopodobnie wkrótce.

1.2 Procesy, wątki i wymiana informacji

W tradycyjnym modelu programowania w systemie Unix w systemie może być jednocześnie wykonywanych kilka procesów, z których każdy ma przydzieloną własną przestrzeń adresową. Ilustruje to ryc. 1.1

Figa. 1.1 Wymiana informacji między procesami


1. Dwa procesy po lewej stronie współużytkują informacje przechowywane w jednym z obiektów systemu plików. Aby uzyskać dostęp do tych danych, każdy proces musi uzyskać dostęp do jądra (przy użyciu funkcji odczytu, zapisu, lseek, zapisu, lseek i tym podobnych). Podczas zmiany pliku wymagana jest pewna forma synchronizacji, aby wyeliminować zakłócenia, gdy kilka procesów jednocześnie zapisuje do pliku i chronić procesy odczytujące z pliku przed tymi, które zapisują do niego.

2. Dwa procesy w środku rysunku współużytkują informacje przechowywane w jądrze. Przykładami w tym przypadku są kanał, kolejka komunikatów lub semafor Systemu V. W takim przypadku wywołania systemowe zostaną wykorzystane do uzyskania dostępu do wspólnych informacji.

3. Dwa procesy po prawej stronie używają wspólnego obszaru pamięci, do którego każdy z procesów może uzyskać dostęp. Po uzyskaniu dostępu do tego obszaru pamięci procesy będą mogły uzyskać dostęp do danych bez pomocy jądra. W tym przypadku, podobnie jak w pierwszym, procesy wykorzystujące pamięć współdzieloną również wymagają synchronizacji.

Należy pamiętać, że w żadnym z tych przypadków liczba interakcji nie jest ograniczona do dwóch. Każda z opisanych metod działa na dowolną liczbę interakcji. Na rysunku przedstawiamy tylko dwa dla uproszczenia.

Strumienie

Chociaż koncepcja procesów w systemach uniksowych istnieje od bardzo dawna, możliwość używania wielu wątków w tym samym procesie jest stosunkowo nowa. Standard wątku Posix.1, zwany Pthreads, został przyjęty w 1995 r. Z punktu widzenia interakcji procesów wszystkie wątki jednego procesu mają wspólne zmienne globalne (to znaczy użycie pamięci współdzielonej jest typowe dla modelu strumieniowego). Jednak wątki wymagają synchronizacji dostępu do danych globalnych. Ogólnie rzecz biorąc, synchronizacja, choć sama w sobie nie jest formą IPC, jest często stosowana w połączeniu z różnymi formami IPC w celu kontroli dostępu do danych.

Ta książka opisuje interakcje między procesami i między wątkami. Zakładamy, że istnieje środowisko, w którym obsługiwane jest programowanie wielowątkowe, i użyjemy wyrażeń w formie „jeśli kanał jest pusty, strumień wywołujący jest blokowany, dopóki jakiś inny strumień nie zapisze kanału”. Jeśli system nie obsługuje strumieni, możesz w tym zdaniu zastąpić „strumienie” „procesami” i otrzymasz klasyczną definicję blokady w systemie Unix, która występuje podczas odczytu z pustego kanału za pomocą polecenia read. Jednak w systemie obsługującym wątki tylko wątek żądający danych z pustego kanału jest blokowany, a wszystkie pozostałe wątki procesu będą nadal działać. Inny wątek tego samego procesu lub jakiś wątek innego procesu może zapisywać dane w kanale.

Dodatek B podsumowuje niektóre podstawowe cechy wątków i opisuje pięć głównych funkcji Pthread używanych w programach w tej książce.

1.3 Przeżywalność obiektu IPC

Można zdefiniować trwałość dowolnego IPC jako czas jego istnienia. Na ryc. 1.2 pokazuje trzy możliwe grupy, do których można przypisać obiekty przeżywalności.

Figa. 1.2 Przeżywalność obiektu IPC


1. Obiekt IPC, którego przeżywalność jest określona przez proces (trwały dla procesu) istnieje, dopóki nie zostanie zamknięty przez ostatni proces, w którym jest nadal otwarty. Przykładem są nienazwane i nazwane potoki (potoki, FIFO).

2. Obiekt IPC, którego przeżywalność zależy od jądra (kernel-persistent), istnieje do momentu ponownego uruchomienia jądra lub do jawnego usunięcia obiektu. Przykładami są kolejki komunikatów Systemu V, semafory i pamięć współdzielona. Przeżywalność kolejek komunikatów, semaforów i pamięci współdzielonej Posix powinna być określana przynajmniej przez jądro, ale może być także określana przez system plików w zależności od implementacji.

3. Obiekt IPC, którego przeżywalność jest określona przez system plików (trwały dla systemu plików) istnieje, dopóki nie zostanie jawnie usunięty. Jego wartość zostaje zachowana nawet po ponownym uruchomieniu jądra. Kolejki komunikatów Posix, semafory i pamięć współdzielona mają tę właściwość, jeśli są realizowane za pomocą wyświetlanych plików (nie zawsze tak jest).

Przy określaniu przeżywalności obiektu IPC należy zachować ostrożność, ponieważ nie zawsze jest to oczywiste. Na przykład dane w potoku są przetwarzane przez jądro, ale o przeżywalności kanałów decydują procesy, a nie rdzeń, ponieważ po ostatnim procesie otwarcia kanału do odczytu zamyka go, jądro zresetuje wszystkie dane i usunie kanał. Podobnie, chociaż kanały FIFO mają nazwy w systemie plików, o ich żywotności decydują również procesy, ponieważ wszystkie dane w takim kanale są resetowane po ostatnim procesie, w którym został otwarty.

Na stole. 1.1 podsumowuje informacje o przeżywalności wcześniej wymienionych obiektów IPC.


Tabela 1.1 Przeżywalność różnych typów obiektów IPC

Typ IPC Witalność determinuje
Kanał programu (potok) Proces
Nazwany rurociąg (FIFO) Proces
Posix Mutual Exception (mutex) Proces
Zmienna warunkowa Posix Proces
Blokada odczytu / zapisu Posix (blokada) Proces
Blokada zapisu FCntl Proces
Kolejka wiadomości Posix Rdzeń
Posix o nazwie semafor (o nazwie semafor) Rdzeń
Semafor posix w pamięci (semafor oparty na pamięci) Proces
Posix Shared Memory (pamięć współdzielona) Rdzeń
Kolejkowanie wiadomości w systemie V. Rdzeń
System semaforowy V. Rdzeń
Rdzeń
Gniazdo TCP Proces
Gniazdo UDP Proces
Gniazdo domeny Unix (gniazdo domeny Unix) Proces

Należy zauważyć, że żaden typ IPC w tej tabeli nie ma przeżywalności zdefiniowanej przez system plików. Wspominaliśmy już, że trzy typy obiektów IPC w standardzie Posix możemają tego rodzaju przeżywalność w zależności od wdrożenia. Oczywiście zapis danych do pliku zapewnia przeżywalność określoną przez system plików, ale zwykle IPC nie są realizowane w ten sposób. Większość obiektów IPC nie jest zaprojektowana tak, aby istniały po ponownym uruchomieniu, ponieważ procesy nie przetrwają. Wymóg przeżycia zdefiniowany przez system plików może obniżyć wydajność tego typu IPC i zwykle jednym z zadań programisty jest zapewnienie wysokiej wydajności.

1.4 Przestrzenie nazw

Jeśli dwa niepowiązane procesy wykorzystują jakiś rodzaj IPC do wymiany informacji, obiekt IPC musi mieć nazwę lub identyfikator, aby jeden z procesów (zwykle nazywany serwerem) mógł utworzyć ten obiekt, a drugi proces (zwykle klientem jest jeden lub więcej klientów) może odnosić się do tego konkretnego obiektu.

Kanały oprogramowania (potoki) nie mają nazw (i dlatego nie mogą być używane do interakcji między niepowiązanymi procesami), ale kanały FIFO są odwzorowywane na nazwy w systemie plików, które są ich identyfikatorami (dlatego kanały FIFO mogą być używane do interakcji między niepowiązanymi procesami). W przypadku innych typów IPC omówionych w dalszych rozdziałach stosuje się dodatkowe konwencje nazewnictwa. Zestaw możliwych nazw dla określonego typu IPC nazywa się jego przestrzenią nazw. Przestrzeń nazw jest ważnym terminem, ponieważ dla wszystkich typów IPC, z wyjątkiem prostych kanałów, nazwa określa sposób, w jaki klient i serwer komunikują się ze sobą w celu przesyłania wiadomości.

Na stole. 1.2 Konwencje nazewnictwa dla różnych typów IPC są podsumowane.


Tabela 1.2 Przestrzenie nazw dla różnych typów IPC

Typ IPC Przestrzeń nazw do utworzenia lub otwarcia ID po otwarciu Posix.1 1996 Unix 98
Kanał (Bez nazwy) Deskryptor
FIFO Nazwa pliku (nazwa ścieżki) Deskryptor
Posix Mutual Exception (Bez nazwy) Wskaźnik typu pthread_mutex_t
Zmienna warunkowa Posix (Bez nazwy) Wskaźnik typu pthread_cond_t
(Bez nazwy) Wskaźnik typu pthread_rwlock_t
Blokada rekordu Fcntl Nazwa pliku Deskryptor
Posix Shared Memory Nazwa IPC Posix Deskryptor
Kolejkowanie wiadomości w systemie V. Klucz key_t Identyfikator V systemu IPC
System semaforowy V. Klucz key_t Identyfikator V systemu IPC
Pamięć współdzielona systemu V. Klucz key_t Identyfikator V systemu IPC
Drzwi Nazwa pliku Deskryptor
Zdalne wywołanie procedury Sun (RPC) Program / wersja Uchwyt RPC
Gniazdo TCP Adres IP i port TCP Deskryptor . 1g
Gniazdo UDP Adres IP i port TCP Deskryptor . 1g
Gniazdo domeny Unix (gniazdo domeny) Pełna nazwa pliku Deskryptor . 1g

Wskazuje również, które formy IPC są zawarte w standardzie Posix.1 z 1996 r., A które zostały zawarte w standardzie Unix 98. Oba te standardy opisano bardziej szczegółowo w sekcji 1.7. Dla porównania w tej tabeli umieściliśmy trzy typy gniazd, które zostały szczegółowo opisane w. Należy pamiętać, że interfejs programu aplikacyjnego (API) jest znormalizowany przez grupę roboczą Posix.1g i powinien stać się częścią standardu Posix.1 w przyszłości.

Chociaż standardem jest Posix. 1 i umożliwia stosowanie semaforów; ich obsługa nie jest obowiązkowa dla producentów. Na stole. 1.3 podsumowano funkcje opisane w standardach Posix.1 i Unix 98. Każda funkcja może być obowiązkowa, nieokreślona lub opcjonalna. W przypadku funkcji opcjonalnych określamy nazwę stałej (na przykład _POSIX_THREADS), która zostanie zdefiniowana (zwykle w pliku nagłówkowym ), jeśli ta funkcja jest obsługiwana. Zauważ, że Unix 98 zawiera Posix.1 jako podzbiór.


Tabela 1.3 Dostępność różnych form IPC

Typ IPC Posix.1 1996 Unix 98
Kanał programowy wymagany wymagany
FIFO wymagany wymagany
Posix Mutual Exception _POSIX_THREADS wymagany
Zmienna warunkowa Posix _POSIX_THREADS wymagany
Wzajemne wyjątki i zmienne warunkowe między procesami _POSIX_THREADS_PROCESS_SHARED wymagany
Blokada odczytu / zapisu Posix (On jest zdefiniowany) wymagany
Blokada rekordu Fcntl wymagany wymagany
Kolejkowanie wiadomości Posix _POSIX_MESSAGE_PASSING _XOPEN_REALTIME
Semafory Posix _POSIX_SEMAPHORES_ _XOPEN_REALTIME
Posix Shared Memory _POSIX_SHARED_MEMORY_OBJECTS _XOPEN_REALTIME
Kolejkowanie wiadomości w systemie V. (On jest zdefiniowany) wymagany
System semaforowy V. (On jest zdefiniowany) wymagany
Pamięć współdzielona systemu V. (On jest zdefiniowany) wymagany
Drzwi (On jest zdefiniowany) (Niezdeterminowany)
Zdalne wywołanie procedury Sun (On jest zdefiniowany) (Niezdeterminowany)
Mapowanie pamięci mapowania _POSIX_MAPPED_FILES lub POSIX_SHARED_MEMORY_OBJECTS wymagany
Sygnały w czasie rzeczywistym (sygnały w czasie rzeczywistym) _POSIX_REALTIME_SIGNALS _XOPEN_REALTIME

1.5 Działanie poleceń fork, exec i exit na obiektach IPC

Musimy zrozumieć wpływ funkcji fork, exec i _exit na różne omawiane przez nas formy IPC (ostatnia z tych funkcji jest wywoływana przez funkcję wyjścia). Informacje na ten temat podsumowano w tabeli. 1.4

Większość funkcji opisano w dalszej części tekstu książki, ale tutaj należy wspomnieć o kilku kwestiach. Po pierwsze, wywołanie fork z procesu wielowątkowego powoduje zamieszanie w bezimiennych zmiennych synchronizacji (wzajemne wyjątki, zmienne warunkowe, blokady i semafory przechowywane w pamięci). Sekcja 6.1 książki zawiera niezbędne szczegóły. Po prostu zauważamy, oprócz tabeli, że jeśli te zmienne są przechowywane we wspólnej pamięci i tworzone za pomocą wspólnego atrybutu dla procesów, będą dostępne dla każdego procesu, który może uzyskać dostęp do tego obszaru pamięci. Po drugie, trzech form Systemu V IPC nie można otworzyć ani zamknąć. Listing 6.6 oraz ćwiczenia 11.1 i 14.1 pokazują, że wszystko, co musisz wiedzieć, aby uzyskać dostęp do tych trzech form IPC, to identyfikator. Dlatego są dostępne dla wszystkich procesów, dla których ten identyfikator jest znany, chociaż pewne semafory i pamięć współdzielona wymagają specjalnego przetwarzania.


Tabela 1.4 Fork, exec i _exit akcja na IPC

Typ IPC widelec exec _wyjście
Potoki nienazwane i nazwane Odrodzony proces otrzymuje kopie wszystkich deskryptorów procesu nadrzędnego Wszystkie otwarte deskryptory pozostają otwarte, jeśli bit FD_CLOEXEC nie jest dla nich ustawiony. Wszystkie otwarte deskryptory są zamknięte, dane z kanału programu i FIFO są usuwane po ostatnim zamknięciu
Kolejkowanie wiadomości Posix Odrodzony proces otrzymuje kopie wszystkich otwartych procesów nadrzędnych Wszystkie otwarte deskryptory kolejek komunikatów są zamknięte.
Kolejki komunikatów w systemie V. To nie działa To nie działa To nie działa
Wzajemne wyjątki i zmienne warunkowe Posix Współdzielone, jeśli używana jest pamięć współdzielona z atrybutem separacji między procesami Znika, jeśli nie znajduje się w pamięci współdzielonej, która pozostaje otwarta i ma dzielony atrybut
Posix Blokady odczytu / zapisu Znika, jeśli nie jest przechowywany w pamięci współdzielonej, która pozostaje otwarta i ma dzielony atrybut Znika, jeśli nie jest przechowywany w pamięci współdzielonej, która pozostaje otwarta i ma dzielony atrybut
Semafory Posix przechowywane w pamięci Udostępnianie, jeśli używana jest pamięć z dostępem współdzielonym i atrybut separacji między procesami Znika, jeśli nie jest przechowywany w pamięci współdzielonej, która pozostaje otwarta i ma dzielony atrybut Znika, jeśli nie jest przechowywany w pamięci współdzielonej, która pozostaje otwarta i ma dzielony atrybut
Posix o nazwie semafory Wszystkie otwarte w procesie nadrzędnym pozostają otwarte w dziecku. Wszystkie otwarte, zamknięte Wszystkie otwarte, zamknięte
Semafory systemu V. Wszystkie wartości semadj w procesie odradzania są ustawione na 0 Wszystkie wartości semadj są przekazywane do nowego programu. Wszystkie wartości semadj są dodawane do odpowiedniej wartości semafora.
Blokada rekordu Fcntl Blokady w procesie nadrzędnym nie są dziedziczone przez proces podrzędny Zamki nie zmieniają się, dopóki uchwyt nie zostanie zamknięty Wszystkie niezerowane blokady ustawione przez proces są odblokowane.
Mapowanie pamięci Odwzorowania pamięci są resetowane (unmap)
Posix Shared Memory Odwzorowania pamięci procesu nadrzędnego są przechowywane w dziecku Odwzorowania pamięci są resetowane Odwzorowania pamięci są resetowane
Pamięć współdzielona systemu V. Dołączone segmenty pamięci wspólnej pozostają dołączone w procesie spawnowania Odłączone segmenty pamięci wspólnej odłączone
Drzwi Odrodzony proces otrzymuje kopie wszystkich otwartych deskryptorów procesu nadrzędnego, ale tylko proces nadrzędny jest serwerem, gdy drzwi są aktywowane za pomocą deskryptorów Wszystkie deskryptory drzwi muszą być zamknięte, ponieważ są tworzone przy użyciu zestawu bitów FD_CLOEXEC. Wszystkie otwarte deskryptory zostaną zamknięte

1.6 Obsługa błędów: funkcje owijania

W każdym prawdziwym programie każde wywołanie wymaga sprawdzenia wartości zwracanej pod kątem błędu. Ponieważ programy zwykle kończą się w przypadku wystąpienia błędów, możemy zmniejszyć ilość tekstu, definiując funkcje otoki, które wykonują rzeczywiste wywołanie funkcji, sprawdzają wartość zwracaną i wychodzą, gdy wystąpią błędy. Zgodnie z konwencjami nazwy funkcji opakowania pokrywają się z nazwami samych funkcji, z wyjątkiem pierwszej litery, na przykład wielkiej litery,

Przykład funkcji opakowania pokazano na Listingu 1.1.

Listing 1.1. Funkcja zawijania do funkcji sem_post
390 if (sem_post (sem) \u003d\u003d –1)
391 err_sys („błąd sem_post”);

Jeśli w tekście widnieje nazwa funkcji rozpoczynająca się od dużej litery, powinieneś wiedzieć: jest to nasza własna funkcja otoki. Wywołuje funkcję o tej samej nazwie rozpoczynającą się od małej litery. Funkcja opakowania kończy proces z komunikatem o błędzie, jeśli taki istnieje.

Opisując kod źródłowy zawarty w książce, zawsze mówimy o wywołanej funkcji najniższego poziomu (na przykład sem_post), a nie o funkcji otoki (na przykład sem_post). Podobnie indeks alfabetyczny zawiera nazwy samych funkcji, a nie ich opakowania.

UWAGA

Powyższy format kodu źródłowego jest używany przez cały czas. Wszystkie niepuste linie są ponumerowane. Tekst opisujący sekcje kodu zaczyna się od liczb pierwszego i ostatniego wiersza w pustym polu po lewej stronie. Czasami przed akapitem tekstu znajduje się krótki pogrubiony nagłówek, opisujący główną treść opisanego kodu.

Na początku kodu podana jest nazwa pliku źródłowego. W tym przykładzie jest to plik wrapunix.c w katalogu lib. Ponieważ kod źródłowy wszystkich przykładów w tej książce jest bezpłatny (patrz przedmowa), możesz łatwo znaleźć potrzebny plik. Kompilowanie, wykonywanie, a zwłaszcza zmienianie tych programów podczas czytania książki jest najlepszym sposobem na poznanie koncepcji interakcji procesów.

Chociaż może się nie wydawać, że korzystanie z takich funkcji otoki jest bardzo opłacalne, poznasz to nieporozumienie w rozdziale 7, w którym stwierdzimy, że funkcje wątków nie przypisują wartości do standardowej zmiennej unikno errno, gdy wystąpi błąd; zamiast tego kod błędu jest po prostu zwracany przez funkcję. Oznacza to, że kiedy wywołujemy funkcję pthread, musimy za każdym razem przydzielać pamięć dla zmiennej, przechowywać w niej wartość zwracaną przez funkcję, a następnie ustawić zmienną errno na tę zmienną przed wywołaniem funkcji err_sys (Listing B.4). Aby nie zaśmiecać tekstu nawiasami klamrowymi, używamy operatora języka C „przecinek” i łączymy przypisanie wartości zmiennej errno i wywołanie err_sys w jednym operatorze, jak w poniższym przykładzie:

if ((n \u003d pthread_mutex_lock (& \u200b\u200bndone_mutex))! \u003d 0) errno \u003d n, err_sys („błąd pthread_mutex_lock”);

Alternatywą jest zdefiniowanie nowej funkcji obsługi błędów, która przyjmuje kod błędu jako argument. Możemy jednak uczynić ten fragment kodu znacznie bardziej czytelnym, pisząc

Pthread_mutex_lock (& \u200b\u200bndone_mutex);

gdzie używamy naszej własnej funkcji opakowania, pokazanej na Listingu 1.2.

Listing 1.2. Implementowanie opakowania dla funkcji pthread_mutex_lock
126 Pthread_mutex_lock (pthread_mutex_t * mptr)
129 if ((n \u003d pthread_mutex_lock (mptr)) \u003d\u003d 0)
132 err_sys („błąd pthread_mutex_lock”);

UWAGA

Ostrożnie wykorzystując możliwości języka C, moglibyśmy użyć makr zamiast funkcji, co zwiększyłoby szybkość wykonywania programu, ale te funkcje opakowania rzadko są (jeśli w ogóle) wąskimi gardłami.

Nasza zgoda na zastąpienie pierwszej litery nazwy funkcji wielką literą jest kompromisem. Rozważano wiele innych form notacji: użycie przedrostka e (), sufiksu _e itp. Nasza opcja wydaje się być najmniej rozpraszająca i jednocześnie daje wizualne wskazanie, że wywoływana jest inna funkcja.

Ta metoda ma boczną przydatną właściwość: sprawdza błędy zwracane przez funkcje, których kod powrotu jest zwykle ignorowany, na przykład close i pthread_ mutex_lock.

W dalszej części tekstu użyjemy tych funkcji opakowania, chyba że będziemy musieli jawnie sprawdzić błąd i przetworzyć go w dowolny sposób, inny niż koniec procesu. Nie udostępniamy kodu źródłowego dla wszystkich opakowań w książce, ale jest on dostępny bezpłatnie w Internecie (patrz wstęp).

Wartość errno

Kiedy wystąpi błąd w funkcji Unix, zmiennej globalnej errno przypisywana jest wartość dodatnia wskazująca rodzaj błędu; funkcja zwykle zwraca wartość –1. Nasza funkcja err_sys wyświetla komunikat odpowiadający kodowi błędu (na przykład Zasób tymczasowo niedostępny - zasób jest tymczasowo niedostępny, jeśli errno jest ustawione na EAGAIN).

Funkcja przypisuje wartość do errno tylko wtedy, gdy wystąpi błąd. W przypadku normalnego wyłączenia wartość tej zmiennej jest niezdefiniowana. Wszystkie wartości dodatnie odpowiadają stałym z wielkimi literami zaczynającymi się na E, zwykle zdefiniowanymi w pliku nagłówkowym . Brak błędów odpowiada wartości 0.

Podczas pracy z wieloma wątkami każdy z nich musi mieć własną zmienną errno. Przydział zmiennej do każdego wątku następuje automatycznie, ale zwykle wymaga to wskazania kompilatorowi, że powinna istnieć możliwość ponownego wejścia do programu. Ustawia się to za pomocą –D_REENTRANT lub –D_POSIX_C_SOURCE \u003d 199506L lub równoważnych kluczy. Często w tytule errno jest definiowane jako makro rozwinięte w wywołanie funkcji, jeśli zdefiniowana jest stała _REENTRANT. Funkcja zapewnia dostęp do kopii errno związanej z tym strumieniem.

W dalszej części tekstu używamy wyrażeń takich jak „funkcja mq_send zwraca EMSGSIZE”, co oznacza, że \u200b\u200bfunkcja zwraca błąd (zwykle zwracana jest wartość –1) i ustawia zmienną errno na wartość określonej stałej.

1.7 Standardy Unix

Standardy uniksowe są obecnie definiowane przez Posix i The Open Group.

Posix

Nazwa Posix pochodzi od „przenośnego interfejsu systemu operacyjnego”, co w przybliżeniu oznacza „przenośny interfejs systemu operacyjnego”. To nie jest jeden standard, ale cała rodzina opracowana przez Instytut Inżynierów Elektryków i Elektroników (IEEE). Normy Posix zostały również przyjęte jako normy międzynarodowe ISO (Międzynarodowa Organizacja Normalizacyjna, Międzynarodowa Organizacja Normalizacyjna) i IEC (Międzynarodowa Komisja Elektrotechniczna, Międzynarodowa Komisja Elektrotechniczna) lub ISO / IEC. Standardy Posix przeszły kilka etapów rozwoju.

■ IEEE 1003.1-1988 (317 stron) był pierwszym standardem Posix. Zdefiniował interfejs interakcji języka C z jądrem typu Unix w następujących obszarach: operacje podstawowe do implementacji procesów (rozwidlenie, wywołania exec, sygnały i timery), środowisko procesu (identyfikatory użytkowników, grupy procesów), pliki i katalogi (wszystkie funkcje I / O) , praca z terminalem, systemowymi bazami danych (hasłami i plikami grupowymi), formatami archiwów tar i cpio.

UWAGA

Pierwszy standard Posix pojawił się w produkcji pod nazwą IEEEIX w 1986 roku. Nazwę Posix zaproponował Richard Stallman.

■ Potem przyszedł standard IEEE 1003.1-1990 (356 stron). Był to również międzynarodowy standard ISO / IEC 9945-1: 1990. W porównaniu do wersji z 1988 roku zmiany w wersji z 1990 roku były minimalne. Dodano nagłówek: „Część 1: Systemowy interfejs aplikacji (API)” („Część 1: Systemowy interfejs programowania aplikacji (API) [Język C])”, co oznaczało, że standard opisuje interfejs programistyczny C (API) .

■ IEEE 1003.2-1992 został opublikowany w dwóch tomach o łącznej objętości około 1300 stron, a jego tytuł zawierał wiersz „Część 2: Shell i narzędzia” (Część 2: „Tłumacz ustny i narzędzia”). Ta część definiowała interpreter (oparty na powłoce Bourne'a w systemie Unix V) i około stu narzędzi (programy zwykle wywoływane z interpretera - od awk i basename do vi i wass). W tej książce będziemy odnosić się do tego standardu pod nazwą Posix. 2)

■ IEEE 1003.1b-1993 (590 stron) był pierwotnie znany jako IEEE P1003.4. Standard ten był dodatkiem do standardu 1003.1-1990 i obejmował rozszerzenia czasu rzeczywistego opracowane przez grupę roboczą P1003.4: synchronizację plików, asynchroniczne operacje we / wy, semafory, zarządzanie pamięcią, planowanie, zegary, liczniki czasu i kolejki komunikatów.

■ IEEE 1003.1, edycja 1996 (743 strony), obejmuje 1003.1-1990 (podstawowy interfejs API), 1003.1b-1993 (rozszerzenia w czasie rzeczywistym), 1003.1-1995 (Pthreads - wątki oprogramowania Posix) i 1003.1i-1995 (zmiany techniczne do 1003,1b). Norma ta nazywa się również ISO / IEC 9945-1: 1996. Dodano do niej trzy rozdziały dotyczące wątków i dodatkowe sekcje dotyczące synchronizacji wątków (wzajemne wykluczenia i zmienne warunkowe), planowania wykonywania wątków i planowania synchronizacji. W tej książce nazywamy ten standard Posix.1.

UWAGA

Ponad jedna czwarta z 743 stron standardu to aplikacja zatytułowana „Uzasadnienie i uwagi” („Uzasadnienie i uwagi”). To uzasadnienie zawiera informacje historyczne i wyjaśnienie powodów, dla których niektóre funkcje zostały lub nie zostały uwzględnione w standardzie. Często uzasadnienie jest nie mniej użyteczne niż sam standard.

Niestety standardy IEEE nie są swobodnie dostępne w Internecie. Informacje o tym, gdzie zamówić książkę, podano w bibliografii pod linkiem. Zauważ, że semafory zostały zdefiniowane w standardzie dla rozszerzeń w czasie rzeczywistym, niezależnie od wzajemnych wykluczeń i zmiennych warunkowych (które zostały zdefiniowane w standardzie Pthreads), co wyjaśnia niektóre różnice w interfejsach API tych narzędzi.

Na koniec zauważ, że blokady do odczytu i zapisu nie są częścią standardów Posix. Jest to opisane bardziej szczegółowo w rozdziale 8.

W przyszłości planowane jest wydanie nowej wersji IEEE 1003.1, która zawiera standardowy interfejs sieciowy P1003.1g (gniazda i XTI), które opisano w pierwszym tomie tej książki.

Przedmowa Posix.1 z 1996 r. Stanowi, że ISO / IEC 9945 składa się z następujących części:

1. Interfejs systemu do tworzenia programów (API) (język C).

2. Tłumacz ustny i narzędzia.

3. Administracja systemem (w fazie rozwoju).

Części 1 i 2 nazywamy Posix.1 i Posix.2.

Trwają prace nad standardami Posix, a autorzy powiązanych z nimi książek muszą strzelać do ruchomego celu. Aktualny status standardów można znaleźć na stronie http://www.pasc.org/standing/sd11.html.

Grupa otwarta

Grupa Open została utworzona w 1996 r. Przez połączenie X / Open Company (założonej w 1984 r.) I Open Software Foundation (OSF, założonej w 1988 r.). Ta grupa jest międzynarodowym konsorcjum producentów i konsumentów z przemysłu, instytucji rządowych i edukacyjnych. Ich standardy pojawiły się również w kilku wersjach:

■ W 1992 r. Opublikowano czwarty numer (wydanie 4), aw 1994 r. Jego drugą wersję (wydanie 4, wersja 2). Ten ostatni jest również znany jako Spec 1170, gdzie magiczna liczba 1170 jest sumą liczby interfejsów systemowych (926), nagłówków (70) i \u200b\u200bpoleceń (174). Istnieją jeszcze dwie nazwy: X / Open Single Unix Specification i Unix 95.

■ W marcu 1997 r. Ogłoszono drugą wersję zunifikowanej specyfikacji Unix. Ten standard oprogramowania nazywa się również Unix 98 i tak odnosimy się do tej specyfikacji w dalszej części książki. Liczba interfejsów w Uniksie 98 wzrosła z 1170 do 1434, chociaż dla stacji roboczej liczba ta sięga 3030, ponieważ liczba ta obejmuje CDE (Common Desktop Environment - wspólne środowisko pulpitu), co z kolei wymaga X Window System i użytkownika Interfejs motywu. Szczegóły tego są zapisane w książce. Przydatne informacje można również znaleźć na stronie http://www.UNIX-systems.org/version2.

UWAGA

Z tej strony możesz swobodnie pobrać zunifikowaną specyfikację Unix prawie w całości.

Wersje Unix i przenośność

Prawie wszystkie wersje Unixa, które możesz dziś spotkać, są zgodne z dowolną wersją standardu Posix.1 lub Posix.2. Mówimy „dowolny”, ponieważ po wprowadzeniu zmian w Posix (na przykład dodanie rozszerzeń w czasie rzeczywistym w 1993 r. I transmisji w 1996 r.) Producenci zwykle potrzebują roku lub dwóch, aby dostosować swoje programy do tych standardów.

Historycznie większość systemów uniksowych jest potomkami BSD lub Systemu V, ale różnice między nimi są stopniowo usuwane, gdy producenci przechodzą na stosowanie standardów Posix. Główne różnice leżą w obszarze administrowania systemem, ponieważ obecnie żaden standard Posix nie opisuje tego obszaru.

W większości przykładów w tej książce korzystaliśmy z systemów operacyjnych Solaris 2.6 i Digital Unix 4.0B. Faktem jest, że w momencie pisania książki (pod koniec 1997 r. - na początku 1998 r.) Tylko te dwa systemy operacyjne obsługiwały wątki oprogramowania System V IPC, Posix IPC i Posix (Pthreads).

1.8 Komentarz do przykładów IPC

Najczęściej trzy szablony (modele) interakcji służą do zilustrowania różnych funkcji w książce:

1. Serwer plików: aplikacja klient-serwer, a klient wysyła żądanie do serwera z nazwą pliku, a serwer zwraca jego zawartość do klienta.

2. Producent-konsument: jeden lub więcej wątków lub procesów (producentów) umieszcza dane w buforze publicznym, a inne wątki lub procesy (konsumenci) wykonują różne operacje na tych danych.

3. Zwiększ numer kolejny: jeden lub więcej wątków lub procesów zwiększa indeks wspólny dla wszystkich. Ten numer może być przechowywany we wspólnym pliku lub we wspólnym obszarze pamięci.

Pierwszy przykład ilustruje różne formy przesyłania wiadomości, podczas gdy dwa pozostałe ilustrują różne rodzaje synchronizacji i wykorzystania pamięci współdzielonej.

Tabele 1.5, 1.6 i 1.7 są rodzajem przewodnika po programach, które opracowujemy na różne tematy przedstawione w książce. Tabele te krótko opisują same programy i wskazują numery odpowiednich ofert.

1.9 Podsumowanie

Interakcja procesowa jest tradycyjnie jednym z obszarów problemowych w Uniksie. W miarę rozwoju systemu proponowano różne rozwiązania i żadne z nich nie było idealne. Klasyfikujemy IPC do czterech głównych typów.

1. Wiadomości (kanały, FIFO, kolejki wiadomości).

2. Synchronizacja (wzajemne wykluczenia, zmienne warunkowe, blokady odczytu i zapisu, semafory).

3. Pamięć współdzielona (nienazwana i nazwana).

4. Procedury wywoływania (drzwi do Solaris, RPC Sun).

Rozważamy interakcję zarówno poszczególnych wątków jednego procesu, jak i kilku niezależnych procesów.

O przeżywalności każdego rodzaju IPC decyduje proces, jądro lub system plików, w zależności od czasu jego istnienia. Przy wyborze rodzaju IPC dla konkretnego zastosowania należy wziąć pod uwagę jego przeżywalność.

Kolejną właściwością każdego typu IPC jest przestrzeń nazw, która definiuje identyfikację obiektów IPC przez procesy i wątki, które z nich korzystają. Niektóre obiekty nie mają nazw (kanały, wzajemne wykluczenia, zmienne warunkowe, blokady odczytu i zapisu), inne mają nazwy w systemie plików (kanały FIFO), inne charakteryzują się tak zwanymi „nazwami Posix IPC” w rozdziale 2 i czwartym - inny rodzaj nazwy opisany w rozdziale 3 (klucze IPC lub identyfikatory systemu V). Zazwyczaj serwer tworzy obiekt IPC o nazwie, a klienci używają tej nazwy w celu uzyskania dostępu do obiektu.

Kody źródłowe podane w książce wykorzystują funkcje otoki opisane w Rozdziale 1.6, aby zmniejszyć ilość kodu, zapewniając jednocześnie kontrolę powrotu błędu dla każdej wywoływanej funkcji. Nazwy wszystkich funkcji opakowania zaczynają się od dużej litery.

Standardy IEEE Posix - Posix.1, który definiuje podstawy interfejsu C w Uniksie, oraz Posix.2, który definiuje podstawowe polecenia, to standardy, do których zmierza większość producentów. Jednak standardy Posix są szybko wchłaniane (dołączane jako część) i są rozszerzane o standardy komercyjne, w szczególności The Open Group (Unix 98).


Tabela 1.5 Wersje modelu klient-serwer

Wymienianie kolejno Opis
4.1 Dwa kanały między procesami nadrzędnymi i podrzędnymi
4.5 Używa popen i kota
4.6 Wykorzystuje dwa kanały FIFO między procesami nadrzędnymi i podrzędnymi
4.7 Dwa kanały FIFO między niezależnym serwerem a niepowiązanym klientem
4.10 Kanały FIFO między niezależnym serwerem szeregowym a wieloma klientami
4.12 Kanał programu lub FIFO: tworzenie rekordów w strumieniu bajtów
6.7 Dwie kolejki komunikatów Systemu V.
6.12 Jedna kolejka komunikatów Systemu V z wieloma klientami
6.16 Jedna kolejka komunikatów System V dla każdego klienta; kilku klientów
15.15 Przełożenie klamki przez drzwi

Tabela 1.6 Wersje modelu producent-konsument

Wymienianie kolejno Opis
7.1 Wzajemne wykluczenie, kilku producentów, jeden konsument
7.5 Wzajemne wykluczenie i zmienna warunkowa, kilku producentów, jeden konsument
10.8 Semafory o nazwie Posix, jeden producent, jeden konsument
10.11 Z myślą o semaforach Posix, jeden producent, jeden konsument
10.12 Posix semafory w pamięci, kilku producentów, jeden konsument
10.15 Posix semafory w pamięci, kilku producentów, kilku konsumentów
10.18 Posix semafory w pamięci, jeden producent, jeden konsument: wiele buforów

Tabela 1.7 Wersje programu z rosnącym numerem kolejnym

Wymienianie kolejno Opis
9.1 Indeks w pliku, bez blokady
9.3 Indeks w pliku, blokada za pomocą fcntl
9.9 Indeks w pliku, blokada przy użyciu funkcji otwarcia
10.10 Indeksuj w pliku, blokuj za pomocą Posix o nazwie semafor
12.2 Indeks mmap pamięci współużytkowanej, blokada przy użyciu semafora o nazwie Posix
12.3 Indeks w pamięci współdzielonej mmap, blokada za pomocą semafora Posix w pamięci
12.4 Indeks w nienazwanej pamięci współużytkowanej 4.4BSD, blokując za pomocą Posix o nazwie semafor
12.5 Indeks pamięci współużytkowanej SVR4 / dev / zero, blokuje przy użyciu semafora o nazwie Posix
13.6 Indeks pamięci współdzielonej Posix, blokada za pomocą semafora Posix w pamięci
A.19 Pomiar wydajności: blokowanie przez wzajemne wykluczanie między wątkami
A.22 Pomiar wydajności: blokada odczytu / zapisu między strumieniami
A.23 Pomiar wydajności: blokowanie między wątkami za pomocą semaforów w pamięci Posix
A.25 Pomiar wydajności: blokowanie między wątkami za pomocą semaforów o nazwie Posix
A.28 Pomiar wydajności: blokowanie między wątkami za pomocą semaforów Systemu V.
A.29 Pomiar wydajności: blokowanie między wątkami za pomocą fcntl
A.33 Pomiar wydajności: blokowanie między procesami za pomocą wzajemnych wyjątków

Ćwiczenia

1. Rysunek 1.1 pokazuje dwa procesy uzyskujące dostęp do jednego pliku. Jeśli oba procesy po prostu dołączą dane na końcu pliku (być może długie), jaki rodzaj synchronizacji będzie potrzebny?

2. Sprawdź plik nagłówka w systemie i dowiedz się, jak zdefiniowane jest errno.

3. Uzupełnij tabelę. 1.3 używane funkcje obsługiwane przez systemy uniksowe.

ROZDZIAŁ 2

2.1 Wprowadzenie

Spośród dostępnych typów IPC następujące trzy można zaklasyfikować jako Posix IPC, czyli metody interakcji procesowej zgodne z Posix:

■ Kolejki komunikatów Posix (rozdział 5);

■ semafory Posix (rozdział 10);

■ Pamięć współdzielona Posix (rozdział 13).

Te trzy typy IPC mają wspólne właściwości, a podobne funkcje są używane do pracy z nimi. W tym rozdziale omówiono ogólne wymagania dotyczące pełnych nazw plików używanych jako identyfikatory, flagi określone podczas otwierania lub tworzenia obiektów IPC oraz uprawnienia dostępu.

Pełna lista funkcji używanych do pracy z tymi typami IPC znajduje się w tabeli. 2.1


Tabela 2.1. Funkcje Posix IPC

Kolejki wiadomości Semafory Wspólna pamięć
Plik nagłówka
Funkcje tworzenia, otwierania i usuwania mq_open mq_close mq_unlink sem_open sem_close sem_unlink sem_init sem_destroy shm_open shm_unlink
Operacje zarządzania mq_getattr mq_setattr ftruncate fstat
Operacje IPC mq_send mq_receive mq_notify sem_wait sem_trywait sem_post sem_getvalue mmap munmap

2.2 Nazwy IPC

Na stole. 1.2 zauważyliśmy, że trzy typy standardu IPC Posix mają identyfikatory (nazwy), które odpowiadają temu standardowi. Nazwa IPC jest przekazywana jako pierwszy argument do jednej z trzech funkcji: mq_open, sem_open i shm_open i nie musi odpowiadać rzeczywistemu plikowi w systemie plików. Standard Posix.1 nakłada następujące ograniczenia na nazwy IPC:

■ Nazwa musi spełniać istniejące wymagania dotyczące nazw plików (nie przekraczać długości bajtów PATHMAX, w tym znaku kończącego o kodzie 0).

■ Jeśli nazwa zaczyna się od ukośnika (/), wywołanie którejkolwiek z tych funkcji spowoduje dostęp do tej samej kolejki. W przeciwnym razie wynik zależy od implementacji.

■ Interpretacja dodatkowych ukośników w nazwie zależy od implementacji.

Dlatego dla lepszej przenośności nazwy powinny zaczynać się od ukośnika (/) i nie mogą zawierać dodatkowych ukośników. Niestety te zasady z kolei prowadzą do problemów z przenośnością.

Solaris 2.6 wymaga początkowego ukośnika i nie pozwala na użycie dodatkowych ukośników. Na przykład dla kolejki komunikatów w katalogu / tmp tworzone są trzy pliki, a nazwy tych plików zaczynają się od .MQ. Na przykład, jeśli argument funkcji mq_open ma postać /queue.1234, wówczas utworzone pliki będą miały nazwy /tmp/.MQDqueue.1234, /tmp/.MQLqueue.1234 i /tmp/.MQPqueue.1234. Jednocześnie w systemie Digital Unix 4.0B tworzony jest po prostu plik o nazwie określonej w momencie wywołania funkcji.

Problem z przenośnością powstaje przy określaniu nazwy z pojedynczym ukośnikiem na początku: musimy mieć uprawnienia do zapisu w katalogu głównym. Na przykład kolejka o nazwie /tmp.1234 jest akceptowalna przez standard Posix i nie spowoduje problemów w systemie Solaris, ale Digital Unix nie utworzy pliku, jeśli nie ma uprawnień do zapisu w katalogu głównym programu. Jeśli podamy nazwę /tmp/test.1234, problemy w systemie Digital Unix i podobnych systemach, które tworzą plik o określonej nazwie, znikną (zakłada się, że istnieje katalog / tmp i program ma pozwolenie na zapis do niego, co jest normalne dla większości systemów uniksowych), jednak korzystanie z Solaris nie będzie możliwe.

Aby rozwiązać takie problemy z przenośnością, należy zdefiniować nazwę w nagłówku za pomocą dyrektywy #define, aby mieć pewność, że można ją łatwo zmienić podczas przenoszenia programu do innego systemu.

UWAGA

Deweloperzy starali się zezwolić na stosowanie kolejek komunikatów, semaforów i pamięci współdzielonej dla istniejących rdzeni Unix oraz w niezależnych systemach bezdyskowych. Jest tak w przypadku, gdy standard jest zbyt ogólny i powoduje problemy z przenośnością. W przypadku Posix nazywa się to „tym, jak standard staje się niestandardowy”.

Standard Posix.1 definiuje trzy makra:

które przyjmują pojedynczy argument - wskaźnik do struktury typu stat, którego zawartość są ustawiane przez funkcje fstat, lstat i stat. Te trzy makra zwracają niezerową wartość, jeśli określony obiekt IPC (kolejka komunikatów, semafor lub segment pamięci dzielonej) jest zaimplementowany jako specjalny rodzaj pliku, a struktura statystyk odnosi się do tego typu. W przeciwnym razie makro zwraca 0.

UWAGA

Niestety użycie tych makr nie jest wystarczające, ponieważ nie ma gwarancji, że te typy IPC zostaną zaimplementowane jako osobne typy plików. Na przykład w Solaris 2.6 wszystkie trzy makra zawsze zwracają 0.

Wszystkie inne makra używane do sprawdzania typu pliku mają nazwy zaczynające się od S_IS i zawsze biorą jeden argument: pole st_mode struktury statystyki. Ponieważ makra używane do testowania typu IPC akceptują argumenty innego typu, ich nazwy zaczynają się od S_TYPEIS.

Funkcja Px_ipc_name

Istnieje inne rozwiązanie tego problemu z przenośnością. Możesz zdefiniować naszą własną funkcję px_ipc_name, która dodaje wymagany katalog jako prefiks do nazwy Posix IPC.

char * px_ipc_name (const char * imię);
/ * Zwraca wskaźnik w przypadku sukcesu, NULL w przypadku błędu * /

UWAGA

Tak wyglądają wykazy naszych własnych funkcji, czyli funkcji, które nie są standardowymi funkcjami systemowymi. Zazwyczaj dołączany jest plik nagłówka unpipc.h (Listing B.1).

Argument łeb(nazwa) nie może zawierać ukośników. Następnie, na przykład, wywołanie px_ipc_name („test1”) zwróci wskaźnik do linii / test1 w Solaris 2.6 lub do linii / tmp / test1 w Digital Unix 4.0B. Pamięć zwracanego ciągu jest dynamicznie przydzielana i zwalniana przez wywołanie free. Możesz ustawić dowolną zmienną środowiskową PX_IPC_NAME, aby ustawić inny domyślny katalog.

Listing 2.1 pokazuje naszą implementację tej funkcji.

UWAGA

Ta lista może być pierwszą funkcją snprintf. Znaczna część istniejących programów używa zamiast tego funkcji sprintf, ale ta ostatnia nie sprawdza przepełnienia bufora odbiorczego. W przeciwieństwie do tego, snprintf przyjmuje rozmiar bufora odbiorczego jako drugi argument, a następnie zapobiega przepełnieniu. Celowe przepełnienie bufora w programie wykorzystującym sprintf było wykorzystywane przez hakerów do łamania systemów od wielu lat.

Funkcja snprintf nie jest jeszcze częścią standardu ANSI C, ale planowane jest włączenie jej do zaktualizowanego standardu o nazwie C9X. Niemniej jednak wielu producentów dołącza ją do standardowej biblioteki C. Wszędzie w tekście używamy funkcji snprintf w naszej własnej wersji, która zapewnia wywołanie sprintf, jeśli funkcja snprinft nie znajduje się w bibliotece systemowej.

Listing 2.1. Funkcja px_ipc_name w naszej implementacji.
3 px_ipc_name (const char * name)
6 if ((dst \u003d malloc (PATN_MAX)) \u003d\u003d NULL)
8 / * można ustawić inną nazwę katalogu za pomocą zmiennej środowiskowej * /
9 if ((dir \u003d getenv („PX IPC_NAME”)) \u003d\u003d NULL) (
11 katalog \u003d POSIX_IPC_PREFIX; / * z „config.h” * /
13 katalog \u003d "/ tmp /"; /* domyślna */
16 / * nazwa katalogu musi kończyć się znakiem „/” * /
17 ukośnik \u003d (reż \u003d\u003d "/")? „”: „/”;
18 snprintf (dst, PATH_MAX, "% s% s% s", katalog, ukośnik, nazwa);
19 zwrot (dst); / * aby uwolnić ten wskaźnik, możesz wywołać free () * /

2.3 Utwórz i otwórz kanały IPC

Wszystkie trzy funkcje używane do tworzenia lub otwierania obiektów IPC: mq_open, sem_open i shm_open, akceptują specjalną flagę oflag jako drugi argument. Definiuje parametry otwarcia żądanego obiektu w taki sam sposób, jak drugi argument standardowej funkcji otwartej. Wszystkie stałe, z których można utworzyć ten argument, podano w tabeli. 2.2


Tabela 2.2 Stałe używane podczas tworzenia i otwierania obiektów IPC

Opis mq_open sem_open shm_open
Tylko czytanie O_RDONLY O_RDONLY
Tylko nagrywaj O_WRONLY
Czytaj i pisz O_RDWR O_RDWR
Utwórz, jeśli nie istnieje O_CREAT O_CREAT O_CREAT
Ekskluzywne stworzenie O_EXCL O_EXCL O_EXCL
Brak blokady O_NONBLOCK
Obetnij istniejący O_TRUNC

Pierwsze trzy wiersze opisują rodzaj dostępu do tworzonego obiektu: tylko do odczytu, tylko do zapisu, do odczytu i zapisu. Kolejkę komunikatów można otworzyć w dowolnym z trzech trybów dostępu, podczas gdy dla semafora wskazanie tych stałych nie jest wymagane (dla każdej operacji z semaforem wymagany jest dostęp do odczytu i zapisu). Wreszcie obiektu pamięci współużytkowanej nie można otworzyć tylko do zapisu.

Wskazanie innych flag z tabeli. 2.2 jest opcjonalny.

O_CREAT - tworzenie kolejki komunikatów, semafora lub segmentu pamięci współdzielonej, jeśli jeszcze nie istnieje (patrz także flaga O_EXCL, która wpływa na wynik).

Podczas tworzenia nowej kolejki komunikatów, semafora lub segmentu pamięci współużytkowanej wymagany jest co najmniej jeden dodatkowy argument określający tryb. Ten argument wskazuje bity uprawnień dostępu do pliku i jest tworzony przez bitowe logiczne dodanie stałych z tabeli. 2.3


Tabela 2.3 Stałe trybu dostępu podczas tworzenia nowego obiektu IPC

Te stałe są zdefiniowane w nagłówku. . Określone bity uprawnień są zmieniane poprzez nałożenie maski trybu tworzenia pliku dla danego procesu (s. 83-85) lub użycie polecenia interpretera umask.

Podobnie jak w przypadku nowo utworzonego pliku, podczas tworzenia kolejki komunikatów, semafora lub segmentu pamięci współużytkowanej przypisuje się im identyfikator użytkownika odpowiadający efektywnemu identyfikatorowi użytkownika procesu. Identyfikator grupy semaforów lub segmentu pamięci współużytkowanej jest ustawiony na bieżący identyfikator procesu grupy lub identyfikator grupy ustawiony domyślnie dla całego systemu. Identyfikator grupy kolejki komunikatów jest zawsze ustawiany jako równy bieżącemu identyfikatorowi grupy procesu (na stronach 77-78 identyfikatory grup i użytkowników są opisane bardziej szczegółowo).

UWAGA

Wydaje się dziwne, że istnieje różnica w ustawianiu identyfikatora grupy dla różnych typów Posix IPC. Identyfikator grupy nowego pliku utworzonego za pomocą funkcji otwarcia jest ustawiony na rzeczywisty identyfikator grupy procesów lub identyfikator grupy katalogów, w której plik jest tworzony, ale funkcje IPC nie mogą z góry zakładać, że dla obiektu IPC w systemie plików tworzony jest prawdziwy plik.

O_EXCL - jeśli ta flaga jest podana jednocześnie z O_CREAT, funkcja tworzy nową kolejkę komunikatów, semafor lub obiekt pamięci współużytkowanej tylko wtedy, gdy nie istnieje. Jeśli obiekt już istnieje, a O_CREAT | O_EXCL, zwracany jest błąd EEXIST.

Weryfikacja istnienia kolejki komunikatów, semafora lub segmentu pamięci współużytkowanej i jego utworzenie (jeśli nie) powinno odbywać się tylko w jednym procesie. Dwie podobne flagi są dostępne w Systemie V IPC, są one opisane w sekcji 3.4.

O_NONBLOCK - ta flaga tworzy kolejkę komunikatów bez blokowania. Blokada jest zwykle ustawiona do odczytu z pustej kolejki lub zapisu do pełnej kolejki. Jest to opisane bardziej szczegółowo w podrozdziałach dotyczących funkcji mq_send i mq_receive w sekcji 5.4.

O_TRUNC - jeśli istniejący segment pamięci współdzielonej jest otwarty do odczytu i zapisu, ta flaga wskazuje na potrzebę zmniejszenia jego rozmiaru do 0.

Na ryc. Rysunek 2.1 pokazuje rzeczywistą sekwencję operacji logicznych podczas otwierania obiektu IPC. Co dokładnie należy rozumieć przez sprawdzanie uprawnień dostępu, opisano w sekcji 2.4. Inne podejście do pokazanego na ryc. 2.1 przedstawiono w tabeli. 2.4

Figa. 2.1 Logika otwierania obiektów IPC


Zauważ, że w środkowym rzędzie tabeli. 2.4, gdzie ustawiona jest tylko flaga O_CREAT, nie otrzymujemy żadnych informacji o tym, czy nowy obiekt został utworzony, czy istniejący został otwarty.


Tabela 2.4 Logika otwierania obiektów IPC

Argument oflag Obiekt nie istnieje Obiekt już istnieje
Brak specjalnych flag Błąd, errno \u003d ENOENT
O_CREAT OK, tworzony jest nowy obiekt. OK, otwiera się istniejący obiekt.
O_CREAT | O_EXCL OK, tworzony jest nowy obiekt. Błąd, errno \u003d EEXIST

2.4 Uprawnienia IPC

Nowa kolejka komunikatów, nazwany semafor lub segment pamięci wspólnej, jest tworzony przez funkcje mq_open, sem_open i shm_open, pod warunkiem, że argument oflag zawiera stałą O_CREAT. Zgodnie z tabelą. 2.3, każdemu z tych typów IPC przypisane są określone uprawnienia, podobne do uprawnień do plików w Uniksie.

Po otwarciu istniejącej kolejki komunikatów, semafora lub segmentu pamięci współużytkowanej z tymi samymi funkcjami (w przypadku, gdy nie określono flagi O_CREAT lub określono O_CREAT bez O_EXCL, a obiekt już istnieje), następuje sprawdzenie uprawnień:

1. Bity uprawnień przypisane do obiektu IPC podczas tworzenia są sprawdzane.

2. Żądany typ dostępu jest sprawdzany (O_RDONLY, O_WRONLY, O_RDWR).

3. Sprawdzany jest poprawny identyfikator użytkownika procesu wywołującego, prawidłowy identyfikator procesu grupy i dodatkowe identyfikatory procesu grupy (ten ostatni może nie być obsługiwany).

Większość systemów uniksowych wykonuje następujące specyficzne kontrole:

1. Jeśli prawidłowym identyfikatorem użytkownika dla procesu jest 0 (użytkownik uprzywilejowany), dostęp będzie dozwolony.

2. Jeśli prawidłowy identyfikator użytkownika procesu jest zgodny z identyfikatorem właściciela obiektu IPC: jeśli ustawiony jest odpowiedni bit uprawnień dla użytkownika, dostęp jest dozwolony, w przeciwnym razie dostęp jest zabroniony.

Pod odpowiednim bitem uprawnień rozumiemy na przykład bit uprawnień do odczytu, jeśli proces otwiera obiekt tylko do odczytu. Jeśli proces otwiera obiekt do zapisu, bit zapisu użytkownika musi być odpowiednio ustawiony.

3. Jeśli bieżący identyfikator grupy procesów lub jeden z dodatkowych identyfikatorów grupy procesów jest zgodny z identyfikatorem grupy obiektów IPC: jeśli ustawiony zostanie odpowiedni bit uprawnień dla grupy, dostęp będzie dozwolony, w przeciwnym razie dostęp zostanie zabroniony.

4. Jeśli ustawiony zostanie odpowiedni bit zezwolenia na dostęp dla innych użytkowników, dostęp będzie dozwolony, w przeciwnym razie dostęp zostanie zabroniony.

Te cztery kontrole są wykonywane w tej kolejności. Dlatego jeśli proces jest właścicielem obiektu IPC (krok 2), dostęp jest dozwolony lub zabroniony tylko na podstawie uprawnień użytkownika (właściciela). Uprawnienia grupy nie są sprawdzane. Podobnie, jeśli proces nie jest właścicielem obiektu IPC, ale należy do żądanej grupy, dostęp jest dozwolony lub zabroniony na podstawie uprawnień grupy - uprawnienia innych użytkowników nie są sprawdzane.

UWAGA

Zgodnie z tabelą. 2.2, funkcja sem_open nie używa flag O_RDONLY, O_WRONLY, O_RDWR. Sekcja 10.2 mówi jednak, że niektóre implementacje Uniksa oznaczają flagę O_RDWR, ponieważ każdy dostęp do semafora wymaga odczytu i zapisu jego wartości.

2.5 Podsumowanie

Trzy typy Posix IPC - kolejki komunikatów, semafory i pamięć współdzielona - są identyfikowane przez ich pełne nazwy. Mogą to być lub nie prawdziwe nazwy plików w systemie plików, co powoduje problemy z przenośnością. Rozwiązaniem tego problemu jest użycie własnej funkcji px_ipc_name. Podczas tworzenia lub otwierania obiektu IPC należy określić zestaw flag podobnych do tych określonych podczas korzystania z funkcji otwierania. Podczas tworzenia nowego obiektu IPC należy określić uprawnienia do niego przy użyciu tych samych stałych S_xxx jak dla funkcji otwartej (Tabela 2.3). Po otwarciu istniejącego obiektu IPC przeprowadzana jest kontrola uprawnień do procesu, podobnie jak podczas otwierania pliku.

Ćwiczenia

1. W jaki sposób bity do ustawienia identyfikatora użytkownika (set-user-ID, SUID) i ustawienia identyfikatora grupy (set-group-ID) (sekcja 4.4) programu używającego Posix IPC wpływają na kontrolę uprawnień opisaną w sekcji 2.4?

2. Kiedy program otwiera obiekt IPC, w jaki sposób może ustalić, czy nowy obiekt IPC został utworzony, czy uzyskuje dostęp do istniejącego obiektu?

ROZDZIAŁ 3

3.1 Wprowadzenie

Spośród dostępnych typów IPC następujące trzy można przypisać do IPC Systemu V, to znaczy do przetwarzania metod interakcji zgodnych ze standardem System V:

■ Kolejki komunikatów Systemu V (rozdział 6);

■ Semafory systemu V (rozdział 11);

■ Pamięć współdzielona systemu V (rozdział 14).

Termin „System V IPC” odnosi się do pochodzenia tych narzędzi: po raz pierwszy pojawiły się one w systemie Unix V. Mają one wiele wspólnego: podobne funkcje służą do organizowania dostępu do obiektów; Również formy przechowywania informacji w jądrze są podobne. W tym rozdziale opisano funkcje wspólne dla trzech rodzajów IPC.

Informacje o funkcjach podsumowano w tabeli. 3.1


Tabela 3.1. Funkcje IPC systemu V.

UWAGA

Informacje na temat historii rozwoju i rozwoju funkcji Systemu IPC nie są zbyt łatwo dostępne. zawiera następujące informacje: kolejki wiadomości, semafory i pamięć współdzieloną tego typu zostały opracowane pod koniec lat 70. w jednym z oddziałów Bell Laboratories w Columbus w Ohio dla jednej wersji Uniksa przeznaczonej do użytku wewnętrznego. Ta wersja nazywała się Columbus Unix lub CB Unix. Wykorzystano go w tzw. Systemach wsparcia operacyjnego - systemach przetwarzania transakcji - do automatyzacji zarządzania i prowadzenia rejestrów w firmie telefonicznej. IPC Systemu V dodano do komercyjnej wersji Unix System V. około 1983 roku.

3.2 Klawisze typu key_t i funkcja ftok

Na stole. 1.2 zauważono, że wartości key_t zastosowano w nazwach trzech typów IPC Systemu V. Plik nagłówka definiuje typ key_t jako liczbę całkowitą (co najmniej 32-bitową). Wartości zmiennych tego typu są zwykle przypisywane przez funkcję ftok.

Funkcja ftok konwertuje istniejącą pełną nazwę i identyfikator liczby całkowitej na wartość typu key_t (zwany kluczem IPC):

key_t ftok (const char * nazwa ścieżki, int iD);
// Zwraca klucz IPC lub -1, jeśli wystąpi błąd

W rzeczywistości funkcja używa pełnej nazwy pliku i 8 niższych bitów identyfikatora, aby utworzyć klucz liczby całkowitej IPC.

Ta funkcja działa przy założeniu, że dla konkretnej aplikacji korzystającej z IPC klient i serwer używają tej samej w pełni kwalifikowanej nazwy obiektu IPC, co ma pewne znaczenie w kontekście aplikacji. Może to być nazwa demona serwera lub nazwa pliku danych używanego przez serwer lub nazwa innego obiektu systemu plików. Jeśli klient i serwer wymagają tylko jednego kanału IPC do komunikacji, można przypisać identyfikator, na przykład wartość 1. Jeśli wymaganych jest kilka kanałów IPC (na przykład jeden z serwera do klienta i jeden w przeciwnym kierunku), identyfikatory muszą mieć różne wartości: na przykład 1 oraz 2. Po tym, jak klient i serwer uzgodnią pełną nazwę i identyfikator, obaj wywołują funkcję ftok w celu uzyskania tego samego klucza IPC.

Większość implementacji ftok wywołuje funkcję stat, a następnie łączy:

■ informacje o systemie plików, do których odnosi się pełna nazwa nazwa ścieżki (pole st_dev struktury statystyki);

■ numer węzła (i-node) w systemie plików (pole st_ino struktury statystyki);

■ 8 niższych bitów identyfikatora (które nie powinny wynosić zero).

Kombinacja tych trzech wartości zwykle daje klucz 32-bitowy. Nie ma gwarancji, że dla dwóch różnych ścieżek o tym samym identyfikatorze zostaną uzyskane różne klucze, ponieważ liczba bitów informacji w trzech wymienionych elementach (identyfikator systemu plików, numer węzła, identyfikator IPC) może przekraczać całkowitą liczbę bitów (patrz Ćwiczenie 3.5 )

UWAGA

Numer węzła jest zawsze niezerowy, więc większość implementacji definiuje stałą IPC_PRIVATE (sekcja 3.4) na zero.

Jeśli określona pełna nazwa nie istnieje lub nie jest dostępna dla procesu wywołującego, ftok zwraca -1. Pamiętaj, że plik, którego nazwa jest używana do obliczania klucza, nie powinien być jednym z plików utworzonych i usuniętych przez serwer podczas pracy, ponieważ za każdym razem, gdy je utworzysz, pliki te otrzymują, ogólnie rzecz biorąc, inny numer węzła, co może zmienić klucz zwrócone przez ftok przy następnym połączeniu.

Przykład

Program z listingu 3.1 przyjmuje pełną nazwę jako argument do linii poleceń, wywołuje funkcje stat i ftok, a następnie wyświetla pola st_dev i st_ino struktury statystyki i wynikowy klucz IPC. Te trzy wartości są wyświetlane w formacie szesnastkowym, więc łatwo jest dokładnie zobaczyć, w jaki sposób generowany jest klucz IPC z tych dwóch wartości i identyfikatora 0x57.

Listing 3.1. Odbieranie i wyświetlanie informacji o pliku i wygenerowanym kluczu IPC
7 err_quit ("wykorzystanie: ftok ");
9 printf ("st_dev: & lx, st_ino:% Ix, klucz:% x \\ n",
10 (u_long) stat.st_dev, (u_long) stat.st_ino,

Uruchomienie tego programu w systemie Solaris 2.6 przyniesie następujące wyniki:

solaris% ftok / etc / system
st_dev: 800018, st_ino: 4a1b, klucz: 57018a1b
solaris% ftok / usr / tmp
st_dev: 800015, st_ino: 10b78, klucz: 57015b78
solaris% ftok /home/rstevens/Mail.out
st_dev: 80001f, st_ino: 3b03, klucz: 5702fb03

Oczywiście, identyfikator identyfikuje wysokie 8 bitów klucza; dolne 12 bitów st_dev definiuje następne 12 bitów klucza, i na koniec, dolne 12 bitów st_ino określa dolne 12 bitów klucza.

Celem tego przykładu nie jest następnie poleganie na takiej metodzie generowania klucza z wymienionych informacji, ale zilustrowanie algorytmu łączenia pełnej nazwy i identyfikatora z konkretną implementacją. W innych implementacjach algorytm może być inny.

UWAGA

FreeBSD używa niższych 8 bitów identyfikatora, niższych 8 bitów st_dev i niższych 16 bitów st_ino.

Zauważ, że mapowanie utworzone przez funkcję ftok jest jednokierunkowe, ponieważ część bitów st_dev i st_ino nie jest używana. Ten klucz nie może określić pełnej nazwy pliku określonej dla obliczeń.

3.3 Struktura Ipc_perm

Dla każdego obiektu IPC, tak jak w przypadku zwykłego pliku, zbiór informacji jest przechowywany w jądrze struktury.

uid_t uid; / * identyfikator użytkownika właściciela * /
gid_t gid / * identyfikator grupy właściciela * /
uid_t cuid; / * identyfikator użytkownika twórcy * /
gid_t cgid; / * identyfikator grupy twórców * /
tryb mode_t; / * uprawnienia do odczytu / zapisu * /
ulong_t seq; / * sekwencyjny numer kanału * /
klucz_t; / * Klucz IPC * /

Struktura ta, wraz z innymi stałymi o zmienionych nazwach dla funkcji IPC systemu V, jest zdefiniowana w pliku . W tym rozdziale opiszemy bardziej szczegółowo pola struktury ipc_perm.


3.4 Utwórz i otwórz kanały IPC

Trzy funkcje getXXX używane do tworzenia lub otwierania obiektów IPC (Tabela 3.1) biorą klucz IPC (typu key_t) jako jeden z argumentów i zwracają identyfikator liczby całkowitej. Ten identyfikator różni się od tego przekazanego do funkcji ftok, jak zobaczymy wkrótce. Aplikacja ma dwie opcje określania klucza (pierwszy argument funkcji getXXX):

1. Zadzwoń do ftok, nadaj mu pełną nazwę i identyfikator.

2. Podaj stałą IPCPRIVATE jako klucz, który gwarantuje utworzenie nowego unikalnego obiektu IPC.

Sekwencja działań jest zilustrowana na ryc. 3.1

Figa. 3.1 Obliczanie identyfikatorów IPC według klucza


Wszystkie trzy funkcje getXXX (tabela 3.1) akceptują zestaw flag jako drugi argument oflag określenie bitów uprawnień do odczytu i zapisu (pole trybu struktury ipc_perm) dla obiektu IPC i określenie, czy nowy obiekt IPC jest tworzony, czy też dostęp do istniejącego jest dostępny. W tym celu obowiązują następujące zasady.

■ Klucz IPC_PRIVATE gwarantuje utworzenie unikalnego obiektu IPC. Brak możliwych kombinacji pełnej nazwy i identyfikatora może spowodować, że funkcja ftok zwróci IPC_PRIVATE jako klucz.

■ Ustawienie bitu argumentu IPC_CREAT oflag prowadzi do utworzenia nowego rekordu dla określonego klucza, jeśli jeszcze nie istnieje. Jeśli zostanie znaleziony istniejący rekord, zwracany jest jego identyfikator.

Jednoczesne ustawienie bitów IPC_CREAT i IPC_EXCL oflagprowadzi do utworzenia nowego rekordu dla określonego klucza tylko wtedy, gdy taki rekord jeszcze nie istnieje. Jeśli zostanie znaleziony istniejący rekord, funkcja zwraca błąd EEXIST (obiekt IPC już istnieje).

Kombinacja IPC_CREAT i IPC_EXCL dla obiektów IPC działa podobnie jak kombinacja O_CREAT i O_EXCL dla funkcji otwartej.

Ustawienie tylko bitu IPC_EXCL bez IPC_CREAT nie ma wpływu.

Logiczny schemat sekwencji działań podczas otwierania obiektu IPC pokazano na ryc. 3.2 Na stole. 3.2 pokazuje alternatywny pogląd na ten proces.

Figa. 3.2 Schemat otwarcia obiektu IPC


Zauważ, że w środkowym rzędzie tabeli. 3.2 dla flagi IPC_CREAT bez IPC_EXCL nie otrzymujemy żadnych informacji o tym, czy nowy obiekt został utworzony, czy dostęp do istniejącego. W przypadku większości aplikacji typowe dla serwera jest tworzenie obiektu IPC za pomocą IPC_CREAT (jeśli nie ma znaczenia, czy obiekt już istnieje) lub IPC_CREAT | IPC_EXCL (jeśli wymagana jest weryfikacja istnienia obiektu). Klient wcale nie wskazuje flag, zakładając, że serwer już utworzył obiekt.

UWAGA

Funkcje IPC w systemie V, w przeciwieństwie do funkcji IPC Posix, definiują własne stałe IPC_xxx zamiast używać O_CREAT i OEXCL, które są akceptowane przez standardową funkcję otwartą (Tabela 2.2).

Zauważ też, że funkcje IPC w Systemie V łączą stałe IPC_xxx z bitami uprawnień (opisanymi w następnej sekcji) w jednym argumencie oflag, podczas gdy funkcja open i funkcja Posix IPC charakteryzują się dwoma argumentami: oflag, w którym ustawione są flagi w postaci O_xxx oraz tryb, który definiuje bity uprawnień dostępu.


Tabela 3.2 Logika tworzenia i otwierania obiektów IPC

Argument oflag Klucz nie istnieje Klucz istnieje
Nie ustawiono specjalnych flag Błąd, errno \u003d ENOENT OK, otwieranie istniejącego obiektu
IPC_CREAT OK, tworzony jest nowy wpis. OK, otwieranie istniejącego
IPC CREAT | IPC_EXCL OK, tworzony jest nowy wpis. Błąd, errno \u003d EEXIST

3.5 Uprawnienia IPC

Podczas tworzenia nowego obiektu IPC przy użyciu jednej z funkcji getXXX wywoływanych za pomocą flagi IPC_CREAT, do struktury ipc_perm wprowadza się następujące informacje (sekcja 3.3):

1. Część bitów argumentu oflag ustaw wartość pola trybu struktury ipc_perm. Na stole. Rysunek 3.3 pokazuje bity uprawnień dla trzech typów IPC (pisanie \u003e\u003e 3 oznacza przesunięcie w prawo o trzy bity).

2. Pola cuid i cgid otrzymują wartości równe prawidłowym identyfikatorom użytkownika i grupy procesu wywołującego. Te dwa pola nazywane są identyfikatorami twórców.

3. Pola uid i gid struktury ipc_perm są również ustawione na równe z prawidłowymi identyfikatorami procesu wywołującego. Te dwa pola są nazywane identyfikatorami właściciela.


Tabela 3.3 Wartości trybu dla uprawnień IPC do odczytu / zapisu

Liczba (ósemkowa) Kolejka wiadomości Semafor Pamięć współdzielona Opis
0400 MSG_R SEM_R SHM_R Przeczytaj użytkownika
0200 MSG_W SEM_A SHM_W Użytkownik - rekord
0040 MSG R \u003e\u003e 3 SEM_R \u003e\u003e 3 SHM_R \u003e\u003e 3 Grupa - Czytanie
0020 MSG_W \u003e\u003e 3 SEM_A \u003e\u003e 3 SHM_W \u003e\u003e 3 Rekord grupy
0004 MSG_R \u003e\u003e 6 SEM_R \u003e\u003e 6 SHM_R \u003e\u003e 6 Inne - czytanie
0002 MSG_W \u003e\u003e 6 SEM_A \u003e\u003e 6 SHM_W \u003e\u003e 6 Inne - nagraj

Identyfikatora twórcy nie można zmienić, natomiast identyfikator właściciela można zmienić w procesie przez wywołanie funkcji ctlXXX dla tego mechanizmu IPC za pomocą polecenia IPC_SET. Trzy funkcje ctlXXX pozwalają procesowi zmienić bity uprawnień dostępu (pole trybu) obiektu IPC.

UWAGA

W większości implementacji zdefiniowano sześć stałych: MSG_R, MSG_W, SEM_R, SEM_A, SHM_R i SHM_W, pokazane w tabeli. 3.3 Te stałe są zdefiniowane w plikach nagłówka. , i . Jednak standard Unix 98 ich nie wymaga. Sufiks A w SEM_A oznacza „alter” (zmiana).

Trzy funkcje getXXX nie używają standardowej maski tworzenia plików w systemie Unix. Uprawnienia do kolejki komunikatów, semafora i pamięci współdzielonej są ustawione dokładnie tak samo, jak argument funkcji.

Posix IPC nie zezwala twórcy IPC na zmianę własności obiektu. Posix nie ma analogów dla komendy IPC_SET. Jednak w Posix IPC nazwa obiektu należy do systemu plików, a zatem właściciela można zmienić jako uprzywilejowanego użytkownika za pomocą komendy chown.

Gdy jakikolwiek proces próbuje uzyskać dostęp do obiektu IPC, przeprowadzana jest kontrola dwuetapowa: przy pierwszym otwarciu pliku (funkcja getXXX), a następnie przy każdym dostępie do obiektu IPC:

1. Podczas konfigurowania dostępu do istniejącego obiektu IPC za pomocą jednej z funkcji getXXX, wykonywane jest wstępne sprawdzenie argumentu oflag proces wywoływania funkcji. Argument nie powinien wskazywać bitów dostępu, które nie są ustawione w polu trybu struktury ipc_perm (dolny kwadrat na ryc. 3.2). Na przykład proces serwera może ustawić wartość elementu trybu dla swojej kolejki komunikatów przychodzących, resetując bity odczytu dla grupy i innych użytkowników. Dowolny proces, który próbuje określić te bity w argumencie oflag funkcja msgget otrzyma błąd. Należy zauważyć, że ta kontrola wygenerowana przez funkcje getXXX jest mało przydatna. Oznacza to, że proces wywołujący zawiera informacje o tym, do której grupy użytkowników należy: może być właścicielem pliku, może należeć do tej samej grupy lub do innych użytkowników. Jeśli proces tworzenia resetuje niektóre bity uprawnień, a proces wywołujący próbuje je ustawić, funkcja getXXX zwróci błąd. Każdy proces może całkowicie pominąć tę kontrolę, podając argument oflag równa 0, jeśli istnienie obiektu IPC jest znane z góry.

2. Dla każdej operacji z obiektami IPC sprawdzane są uprawnienia dla procesu żądającego tej operacji. Na przykład za każdym razem, gdy proces próbuje ustawić wiadomość w kolejce za pomocą komendy msgsnd, wykonywane są następujące kontrole (kolejne kroki są pomijane przy uzyskiwaniu dostępu).

□ Użytkownik uprzywilejowany ma zawsze dostęp.

□ Jeśli prawidłowy identyfikator użytkownika pasuje do identyfikatora UID lub CUID obiektu IPC, a odpowiedni bit zezwolenia na dostęp jest ustawiony w polu trybu obiektu IPC, dostęp będzie dozwolony. Przez odpowiedni bit zezwolenia na dostęp rozumie się bit, który pozwala na odczyt, jeśli proces wywołujący zażąda operacji odczytu dla tego obiektu IPC (na przykład otrzymanie komunikatu z kolejki), lub bit, który pozwala na zapis, jeśli proces chce go wykonać.

□ Jeśli prawidłowy identyfikator grupy odpowiada wartości gid lub cgid obiektu IPC, a odpowiedni bit zezwolenia na dostęp jest ustawiony w polu trybu obiektu IPC, dostęp będzie dozwolony.

□ Jeśli dostęp nie był dozwolony w poprzednich krokach, sprawdzana jest obecność odpowiednich bitów dostępu dla innych użytkowników.

3.6 Ponowne użycie identyfikatora

Struktura ipc_perm (sekcja 3.3) zawiera zmienną seq, która przechowuje numer seryjny kanału. Ta zmienna jest licznikiem uruchamianym przez jądro dla każdego obiektu IPC w systemie. Kiedy obiekt IPC zostanie usunięty, numer kanału wzrasta, a gdy się przepełnia, resetuje się do zera.

UWAGA

W tej sekcji opisujemy implementację specyficzną dla SVR4. Standard Unix 98 nie wyklucza korzystania z innych opcji.

Istnieje potrzeba licznika z dwóch powodów. Najpierw przywołaj deskryptory plików przechowywane w jądrze dla każdego z otwartych plików. Są to zwykle małe liczby całkowite, które mają znaczenie tylko w jednym procesie - dla każdego procesu tworzone są jego własne deskryptory. Możesz odczytać z pliku z deskryptorem 4 tylko w procesie, w którym istnieje otwarty plik z takim deskryptorem. To, czy w innych procesach są otwarte pliki z tym samym deskryptorem, nie ma znaczenia. W przeciwieństwie do deskryptorów plików, identyfikatory IPC systemu V są ustawiane dla całego systemu, a nie dla całego procesu.

Identyfikator IPC jest zwracany przez jedną z funkcji getXXX: msgget, semget, shmget. Podobnie jak deskryptory plików, identyfikatory są liczbami całkowitymi, które w przeciwieństwie do deskryptorów mają tę samą wartość dla wszystkich procesów. Jeśli dwa niepowiązane procesy (klient i serwer) używają tej samej kolejki komunikatów, jej identyfikator zwrócony przez funkcję msgget musi mieć tę samą wartość całkowitą w obu procesach, aby mogły uzyskać dostęp do tej samej kolejki. Ta funkcja umożliwia dowolnemu procesowi utworzonemu przez atakującego próbę odczytania wiadomości z kolejki utworzonej przez inną aplikację, sekwencyjnego sortowania według różnych identyfikatorów (jeśli były to liczby całkowite) i liczenia na istnienie kolejki, która jest obecnie otwarta i dostępna dla wszystkich. . Gdyby identyfikatory były małymi liczbami całkowitymi (jak deskryptory plików), prawdopodobieństwo znalezienia poprawnego identyfikatora wynosiłoby około 1/50 (zakładając ograniczenie do 50 deskryptorów procesu).

Aby wyeliminować tę możliwość, twórcy narzędzi IPC postanowili rozszerzyć możliwy zakres wartości identyfikatora, tak aby obejmował on wszystkie liczby całkowite, a nie tylko małe. Rozszerzenie zakresu zapewnia zwiększenie wartości identyfikatora zwróconego do procesu wywołującego o liczbę wpisów w tabeli systemowej IPC za każdym razem, gdy jeden z nich jest ponownie wykorzystywany. Na przykład, jeśli system jest skonfigurowany do używania nie więcej niż 50 kolejek komunikatów, identyfikator 0 zostanie zwrócony do procesu, gdy pierwszy rekord zostanie użyty po raz pierwszy. Po usunięciu tej kolejki komunikatów, podczas próby ponownego użycia pierwszego rekordu w tabeli, identyfikator 50 zostanie zwrócony. Następnie przyjmie wartości 100, 150 itd. Ponieważ sekwencja jest zwykle definiowana jako długa liczba całkowita bez znaku (ulong - patrz struktura ipc_perm w sekcji 3.3), powrót do już używanych identyfikatorów występuje, gdy wpis w tabeli jest używany 85899346 razy (2³² / 50 przy założeniu, że liczba całkowita jest 32-bitowa).

Drugim powodem, dla którego trzeba było wprowadzić numer seryjny kanału, jest konieczność wyeliminowania ponownego użycia identyfikatorów Systemu IPC po krótkim czasie. Pomaga to zapewnić, że serwer, który został przedwcześnie zakończony, a następnie zrestartowany, nie używa tego samego identyfikatora.

Aby zilustrować tę funkcję, program z listingu 3.2 wyświetla pierwsze dziesięć wartości identyfikatora zwróconych przez msgget.

Listing 3.2. Dane wyjściowe identyfikatora kolejki komunikatów dziesięć razy z rzędu
7 msqid \u003d Msgget (IPC_PRIVATE, SVMSG_MODE | IPC_CREAT);
8 printf ("msqid \u003d% d \\ n", msqid);
9 Msgctl (msqid, IPC_RMID, NULL);

Przy następnym przejściu pętli msgget tworzy kolejkę komunikatów, a msgctl z komendą IPC_RMID jako argument usuwa ją. Stała SVMSG_MODE jest zdefiniowana w naszym pliku nagłówkowym unpipc.h (Listing B.1) i ustawia domyślne uprawnienia dla kolejki komunikatów System V. Wyjście programu będzie wyglądać następująco:

Po ponownym uruchomieniu programu zobaczymy wyraźną ilustrację faktu, że numer seryjny kanału jest zmienną przechowywaną w jądrze i nadal istnieje nawet po zakończeniu procesu.

3.7 Programy IPC i IPCRM

Ponieważ obiekty IPC w Systemie V nie są mapowane na nazwy w systemie plików, nie możemy wyświetlić ich listy ani usunąć ich za pomocą standardowych programów ls i rm. Zamiast tego w systemach obsługujących te typy IPC dostarczane są dwa specjalne programy: ipcs, który wyświetla różne informacje o właściwościach IPC Systemu V, i ipcrm, który usuwa kolejkę komunikatów Systemu V, semafor lub segment pamięci dzielonej. Pierwsza z tych funkcji obsługuje około tuzina opcji wiersza polecenia, które kontrolują wyświetlanie informacji o różnych typach IPC. Drugi (ipcrm) może określać maksymalnie sześć parametrów. Szczegółowe informacje na ich temat można uzyskać w systemie pomocy.

UWAGA

Ponieważ IPC w Systemie V nie jest standaryzowany przez Posix, te polecenia nie są częścią Posix.2. Są one opisane w standardzie Unix 98.

3.8 Ograniczenia jądra

Większość implementacji IPC w Systemie V charakteryzuje się wewnętrznymi ograniczeniami jądra. Jest to na przykład maksymalna liczba kolejek komunikatów lub ograniczenie maksymalnej liczby semaforów w zestawie. Wartości charakterystyczne tych ograniczeń podano w tabeli. 6.2, 11.1 i 14.1. Większość ograniczeń jest dziedziczona z pierwotnego wdrożenia Systemu V.

UWAGA

Sekcja 11.2 książki i rozdział 8 opisują implementację kolejek komunikatów, semaforów i pamięci współdzielonej w systemie V. Niektóre z tych ograniczeń są już tam opisane.

Niestety niektóre z nałożonych ograniczeń są dość rygorystyczne, ponieważ zostały odziedziczone z oryginalnej implementacji, która była oparta na systemie z małą przestrzenią adresową (16-bitowy PDP-11). Na szczęście większość systemów pozwala administratorowi modyfikować niektóre domyślne ograniczenia, ale wymagane do tego kroki są specyficzne dla każdej wersji Uniksa. W większości przypadków po wprowadzeniu zmian wymagane jest ponowne uruchomienie jądra. Niestety, niektóre implementacje nadal używają 16-bitowych liczb całkowitych do przechowywania niektórych parametrów, a to już ustawia ograniczenia sprzętowe.

Na przykład w Solaris 2.6 istnieją takie ograniczenia 20. Ich bieżące wartości można wyświetlić za pomocą polecenia sysdef. Zauważ, że zamiast rzeczywistych wartości, zera będą wyświetlane, jeśli odpowiedni moduł jądra nie jest załadowany (to znaczy, narzędzie nie było wcześniej używane). Można to wyeliminować, dodając dowolne z poniższych instrukcji do pliku systemowego / etc /. Plik / etc / system jest odczytywany podczas restartu systemu:

ustaw msgsys: msginfo_msgseg \u003d wartość
ustaw msgsys: msginfo_msgssz \u003d wartość
ustaw msgsys: msginfo_msgtql \u003d wartość
ustaw msgsys: msginfo_msgmap \u003d wartość
ustaw msgsys: msginfo_msgmax \u003d wartość
ustaw msgsys: msginfo_msgmnb \u003d wartość
ustaw msgsys: msginfo_msgmni \u003d wartość

set semsys: seminfo_semopm \u003d wartość
set semsys: seminfo_semume \u003d wartość
set semsys: seminfo_semaem \u003d wartość
set semsys: seminfo_semmap \u003d wartość
set semsys: seminfo_semvmx \u003d wartość
set semsys: seminfo_semmsl \u003d wartość
set semsys: seminfo_semmni \u003d wartość
set semsys: seminfo_semmns \u003d wartość
set semsys: seminfo_semmnu \u003d wartość

ustaw shmsys: shminfo_shmmin \u003d wartość
ustaw shmsys: shminfo_shmseg \u003d wartość
ustaw shmsys: shminfo_shmmax \u003d wartość
ustaw shmsys: shminfo_shmmni \u003d wartość

Ostatnie sześć znaków nazwy po lewej stronie znaku równości to zmienne wymienione w tabeli. 6.2, 11.1 i 14.1.

W Digital Unix 4.0B sysconfig pozwala na naukę lub zmianę wielu parametrów i ograniczeń jądra. Poniżej przedstawiono wynik działania tego polecenia, uruchomionego z opcją –q. Polecenie wyświetla bieżące ograniczenia dla podsystemu ipc. Niektóre wiersze w danych wyjściowych, które nie są związane z narzędziami IPC System V, zostały pominięte:

alfa% / sbin / sysconfig –q ipc

Możesz określić inne wartości domyślne dla tych opcji, modyfikując plik / etc / sysconfigtab. Należy to zrobić za pomocą programu sysconfigdb. Ten plik jest także odczytywany podczas procesu uruchamiania systemu.

3,9 Podsumowanie

Pierwszym argumentem funkcji msgget, semget i shmget jest klucz IPC System V. Klucze te są obliczane na podstawie pełnej nazwy pliku przy użyciu funkcji systemowej ftok. Klucz można również ustawić na IPCPRIVATE. Te trzy funkcje tworzą nowy obiekt IPC lub otwierają istniejący i zwracają identyfikator IPC Systemu V, liczbę całkowitą, która jest następnie używana do rozpoznania obiektu w innych funkcjach związanych z IPC. Te identyfikatory mają sens nie tylko w ramach jednego procesu (jak deskryptory plików), ale także w całym systemie. Mogą być ponownie wykorzystane przez rdzeń, ale dopiero po pewnym czasie.

Struktura ipc_perm jest powiązana z każdym obiektem IPC systemu V, który zawiera informacje o nim, takie jak identyfikator użytkownika właściciela, identyfikator grupy, uprawnienia do odczytu i zapisu itp. Jedną z różnic między systemem V i Posix IPC jest to, że dotyczy obiektu IPC systemu V informacje są zawsze dostępne (dostęp do nich można uzyskać za pomocą jednej z funkcji XXXctl z argumentem IPC_STAT), a w Posix dostęp do IPC zależy od implementacji. Jeśli obiekt Posix IPC jest przechowywany w systemie plików i znamy w nim jego nazwę, możemy uzyskać dostęp do tych informacji za pomocą standardowych narzędzi systemu plików.

Podczas tworzenia nowego lub otwierania istniejącego obiektu IPC Systemu V, getXXX przekazuje dwie flagi (IPC_CREAT i IPC_EXCL) i 9 bitów uprawnień.

Bez wątpienia podstawowym problemem związanym z używaniem Systemu V IPC są sztuczne ograniczenia w większości implementacji. Ograniczenia są nakładane na rozmiar obiektów i wywodzą się z pierwszych implementacji. Oznacza to, że intensywne korzystanie z Systemu V przez aplikacje IPC wymaga zmiany ograniczeń jądra, a zmiany te są wprowadzane inaczej w każdym systemie.

Ćwiczenia

1. Przeczytaj o funkcji msgctl w rozdziale 6.5 i zmodyfikuj program na Listingu 3.2, aby wyświetlał się nie tylko identyfikator, ale także pole seq struktury ipc_perm.

2. Natychmiast po uruchomieniu Listingu 3.2 uruchamiamy program, który tworzy dwie kolejki komunikatów. Zakładając, że żadna inna aplikacja nie używała kolejek komunikatów od czasu uruchomienia systemu, określ, które wartości zostaną zwrócone przez msgget jako identyfikatory kolejki komunikatów.

3. W sekcji 3.5 zauważono, że funkcje IPC getXXX System V nie używają maski tworzenia plików. Napisz program testowy, który tworzy kanał FIFO (używając funkcji mkfifo opisanej w Rozdziale 4.6) i kolejki komunikatów Systemu V, określając zarówno rozdzielczość 666 (w formacie ósemkowym). Porównaj uprawnienia dla utworzonych obiektów (FIFO i kolejki komunikatów). Przed uruchomieniem programu upewnij się, że wartość umask jest niezerowa.

4. Serwer musi utworzyć unikalną kolejkę komunikatów dla swoich klientów. Co jest lepsze: użyć jakiejś stałej nazwy pliku (na przykład nazwy serwera) jako argumentu funkcji ftok lub użyć klucza IPC_PRIVATE?

5. Zmodyfikuj Listing 3.1, aby wyświetlał się tylko klucz IPC i ścieżka pliku. Uruchom program find, aby wyświetlić listę wszystkich plików w systemie plików i przekazać dane wyjściowe do nowo utworzonego programu. Ile nazw plików będzie odpowiadał ten sam klucz?

6. Jeśli twój system ma program sar (raport aktywności systemu - informacja o aktywności systemu), uruchom komendę

Liczba operacji na sekundę z kolejkami komunikatów i semaforami mierzona co 5 sekund 6 razy zostanie wyświetlona na ekranie.

Uwagi:

IPC jest pojęciem związanym z, ale sensowniej jest zrozumieć, co to jest bardziej szczegółowo.

Zadowolony:

Strona teoretyczna

Każdy przynajmniej trochę wyobraża sobie działanie zwykłego systemu operacyjnego.

Wyobraźmy sobie teraz, że działanie naszego znanego nam systemu operacyjnego zmieniło się w jego złego dwoistego, który nie tylko nie wygląda jak oryginalny, ale także wypełnia wszystkie swoje obowiązki.

Taki rozwój mógłby się wydarzyć, gdyby nie był wbudowany w nasz system IPC.

Jeśli dobrze przestudiujesz kwestię zależności programów od siebie, możesz zrozumieć, że istnieje wiele aplikacji, które nie są od siebie zależne.

Jest to dość logiczne, ponieważ dla wysokiego współczynnika działania dowolnego systemu konieczne jest po prostu między komponentami.

Na przykład, gdy dana osoba ma pytanie w swojej pracy, które zależy od jej pracy, bierze informacje, których potrzebuje, z jakiegoś źródła, czy to osoby, czy innego źródła.

Chociaż „rdzeniem” naszego komputera jest wyszukiwanie informacji w określonym źródle, zasada działania robotów jest zasadniczo taka sama.

Zasada działania

Aby zapewnić prawidłowe funkcjonowanie systemu, aplikacje muszą koniecznie mieć ciągłą komunikację lub same muszą dostarczyć niezbędne informacje na żądanie procesów.

Właśnie z powodu potrzeby stałej wymiany informacji z aplikacjami w systemie operacyjnym wbudowanych jest wiele mechanizmów odpowiedzialnych za utrzymanie stałego i bezbłędnego przepływu informacji.

Takie mechanizmy lub programy nazywane są „komunikacją międzyprocesową” - z tłumaczeniem Komunikacja międzyprocesowa (IPC).

Ważny: IPC to mechanizm lub program zapewniający stabilną wzajemną wymianę danych między przepływami / procesorami informacji o procesie.

Ten program działa bezpośrednio w samym systemie operacyjnym i jest podstawą do przesyłania wszelkich informacji.

Przykłady IPC

Jeszcze przed opracowaniem technologii sieciowych istotna stała się kwestia potrzeby przesyłania informacji z procesora do procesora działającego na jednym komputerze.

Istnieje tylko ogromna liczba przykładów, kiedy ten program był używany w dość prymitywnych, jak na razie, mechanizmach.

Rozważ jeden z kluczowych przykładów, który jasno ilustruje znaczenie IPC nawet w bardzo prostych i wczesnych systemach, nie mówiąc już o jej dzisiejszych potrzebach.

Starsze wersje współczesnego IPC były nadal obecne w MS-DOS.

W procesie rozwoju technologii, gdy technologie sieciowe i systemy dopiero zaczynały swoją długą ścieżkę rozwoju, zaczęła pojawiać się potrzeba mechanizmów tworzących połączone procesory, które są wdrażane w jednej sieci.

W tym czasie rozwiązanie tego problemu było bardzo problematyczne.

Faktem jest, że takie połączenie mogłoby wymieniać dane, gdyby tylko ich platformy lub systemy operacyjne należały do \u200b\u200btych samych modeli.

W nowoczesnej sieci problemy te od dawna nikomu nie przeszkadzały. Oto krótki przykładowy przykład pracy w takich sieciach.

Te procesy są wykonywane na dwóch różnych komputerach, w dwóch różnych miejscach:

  • przeglądarka w twoim systemie
  • serwer - w dowolnym innym systemie lub absolutnie w dowolnym miejscu.

I wcale nie zastanawiasz się, jakiego rodzaju serwerami jest system operacyjny.

Nawiązując do ogólnej zasady działania takich formularzy, jak IPC, i nie tylko takich, stosuje się głównie koncepcję klient-serwer.

Oczywiste jest, że „klient” to aplikacja, która żąda informacji, a prośba o informacje trafia już do „serwera” - aplikacji, która dostarcza niezbędnych informacji.

Ogólne stanowisko

Po rozważeniu wszystkich możliwości i przykładów korzystania z komunikacji międzyprocesowej możesz sam upewnić się, że to oprogramowanie jest po prostu niezbędne dla systemu operacyjnego, z którym jesteśmy przyzwyczajeni.

Obszary interakcji IPC zostaną wymienione poniżej, zarówno w jednym systemie, jak iw sieci z wieloma użytkownikami.

Obecnie wymagania dotyczące systemów operacyjnych rosną proporcjonalnie do poziomu technologii.

Wzrost ten jest spowodowany faktem, że każdego dnia do naszych systemów operacyjnych przybywa coraz więcej dodatków, które z kolei poprawiają właściwości naszego komputera.

Ale niewiele osób wie, że nowoczesne systemy operacyjne obsługujące powinny mieć takie programy lub mechanizmy, które zapewnią synchronizację procesorów bez wzajemnych wyjątków i przy minimalnych opóźnieniach.

Te kryteria są bardzo ważne w działaniu naszego komputera.

Jeśli mówimy o idealnym systemie wielozadaniowym, wówczas wszystkie działające w nim procesy powinny być od siebie niezależne, to znaczy być asynchroniczne.

W rzeczywistości taki „idealny” system jest niemożliwy, ponieważ wcześniej czy później powstają sytuacje, gdy procesy potrzebują dostępu do niektórych współdzielonych zasobów.

Aby uzyskać tę możliwość, na poziomie systemu operacyjnego zapewniane są specjalne zasoby, które zapewniają im taką możliwość.

Ale tutaj oczywiście nie bez wyjątków. Uruchamianie równoległych procesów może powodować problemy.

Na przykład: pracując razem, każdy proces, który uzyskuje dostęp do współdzielonych danych, uniemożliwia wszystkim innym procesom jednoczesny dostęp do tych danych - zjawisko to nazywa się wzajemnym wykluczeniem.

Trzy główne typy IPC

  • Lokalny

Ten typ IPC jest całkowicie podłączony do twojego komputera; praca odbywa się tylko w granicach jednego systemu (komputera).

Jest to główna i obowiązkowa praca procesów zapewniających transfer danych przez system, a mianowicie kanały, kolejki komunikatów i pamięć współdzielona.

Ze względu na swoje ograniczenia pod względem przestrzeni komunikacyjnej dane IPC mogą działać tylko w ramach własnych limitów.

Ale dzięki temu ograniczeniu można do nich używać szybszych i prostszych interfejsów.

  • Zdalny

Aby zapewnić interakcję w systemie z jednym procesorem lub między programami na różnych procesorach podłączonych przez tę samą sieć, stosowane są specjalne mechanizmy zapewniające zdalne IPC.

  • Wysoki poziom

Ostatni i być może jeden z najtrudniejszych w użyciu typów IPC - wysokiego poziomu.

Ten widok jest pakietem oprogramowania.

Ten pakiet danych tworzy tak zwaną „warstwę środkową”, która zapewnia możliwość komunikacji między platformą systemową a aplikacją.

Zapewnienie prawidłowego działania wymiany danych

Wraz z jego główną funkcją, zapewniającą interakcję procesora, narzędzia ICP są powiązane z rozwiązywaniem problemów pojawiających się przy organizacji obliczeń równoległych.

Oto przykłady ich obszaru działalności:

1 DOkonkurencyjnymi sytuacje między procesami.Możemy sobie wyobrazić idealny system, w którym odbywa się tylko jedna akcja, czyli odczyt danych z jednego pliku. Ten system jest całkowicie spokojny, dopóki jeden z procesów nie będzie musiał zmienić tego pliku. W takim przypadku między procesami powstaje „sytuacja konkurencyjna”. Można to porównać do kamyka w jakimś mechanizmie.

2 Informacje o sekwencyjnym nagrywaniu w kolejce. Aby zapewnić użytkownikom możliwość szybkiego i niezawodnego rejestrowania danych, tworzone są specjalne kolejki. Myślę, że wiesz, co to jest linia. Ale w rzeczywistości tworzone są nie jedna, ale dwie kolejki. Te kolejki różnią się od rzeczywistych tylko tym, że jedna z nich służy tylko do odczytu, a druga już pozwala nam rejestrować niezbędne informacje. Ta kolejka jest tworzona, aby zapobiec zakleszczeniom, które omówimy nieco później.

Co z tymi procesami, które wymagają nieodłącznej szybkości ich decyzji?

Wcześniej podczas tworzenia wyżej wymienionych kolejek pojawiał się problem, w którym niektóre procesy mogły czekać długo na kolejkę w czasie, gdy ten proces był pilny.

Po pewnym czasie chodziło o stworzenie kolejek, które przeprowadzałyby taką rutynę procesów, która nie kolidowałaby z głównymi lub ważniejszymi procesami.

Istnieje również termin, który zarówno w teorii, jak i w praktyce jest uzasadniony jego nazwą - to ślepy zaułek.

Jego szczególną cechą jest to, że chociaż procesy zostały już uwolnione, nie mogą przejść do następnego kroku, aby zakończyć proces.

Jeśli łatwiej to wytłumaczyć, w praktyce uzyskuje się następujące: mamy proces X, gdy uzyskuje dostęp do pliku X, zaczyna czekać na zwolnienie pliku Y, aby zakończyć swoją pracę. Ale wraz z nimi proces Y, po uzyskaniu dostępu do pliku Y, czeka, aż plik X zostanie zwolniony.

Procesy te są obecnie zamknięte między sobą i czekają na wzajemne zwolnienie pliku, nie uwalniając go.

Takiego „zamknięcia” można uniknąć, jeśli użytkownik upewni się, że zasoby są ponumerowane.

Muszą być również budowane ściśle w rosnącej kolejności liczb.

Aktualne przykłady ICP

Aby zwizualizować interakcję programów na jednym komputerze, istnieje znany zasób - schowek.

Nie zdziw się, nasz stary dobry schowek jest również jednym z mechanizmów IPC.

A zasada jego działania jest następująca: tekst wybrany z edytora tekstu po zaznaczeniu jest umieszczany w lub w tym samym programie do układu.

Sam możesz zobaczyć, że ślady mechanizmów komunikacji międzyprocesowej można znaleźć nawet w drobnych szczegółach.

Podjęto wiele prób stworzenia programów lub mechanizmów, które zapewniłyby szybki i wydajny transfer informacji między procesorami.

Chociaż powstało całkiem sporo takich narzędzi, wiele z nich jest nadal zachowanych lub służyło jako podstawa przyszłych modeli.

Warto zauważyć, że wiele z nich zostało zaimplementowanych w Windows 9x, a jeszcze więcej w Windows NT / 2000.

Chciałbym zwrócić uwagę na fakt, że istnienie uniwersalnego sposobu wymiany danych, który byłby użyteczny we wszystkich sytuacjach, jest po prostu niemożliwe.

Bez względu na środowisko, w które wchodzi użytkownik - preferowana jest dokładnie jedna z tych metod, chociaż nie ma między nimi dużej różnicy w normalnych warunkach.

Możemy jednak zapewnić, że po tym artykule nawigacja w zasobach związanych z IPC lub wyborem konkretnej metody robota nie będzie już trudna, ważąc wszystkie zalety i wady.

Dla tych, którzy myślą, że rozwój tej technologii nie jest zapowiedzią, jest jeden fakt, który zmieni zdanie.

Programy i mechanizmy związane z IPC są bezpośrednio związane z systemem operacyjnym. Oznacza to, że wydajność i niezawodność tych zasobów będą rosły wraz z ulepszaniem robotów.

Wielu użytkowników sieci lokalnych często nie podejrzewa, że \u200b\u200bich dyski to zasoby sieciowe, z którymi można się połączyć, zwane ukrytymi zasobami administracyjnymi i współdzielonymi C $, ADMIN $, FAKS $, IPC $, PRINT $. Musisz je wyłączyć, jeśli ich nie potrzebujesz!

Rodzaje udziałów sieciowych w systemie Windows XP / 200

Domyślnie w systemie Windows XP / 2000 można tworzyć następujące ukryte udziały administracyjne:

  1. partycje główne lub woluminy C $ ( D $, E $, F $ itp.);
  2. katalog główny systemu operacyjnego ADMIN $
  3. udział FAKSU $
  4. udział IPC $
  5. udostępnij PRINT $.

Dla partycji głównych i woluminów jako nazwa udostępnionego zasobu używana jest nazwa dysku, dla którego symbol „ $ „. Na przykład, aby uzyskać dostęp do dysków do i re udostępnione zasoby zostaną utworzone C $ i D $.

Katalog główny systemu operacyjnego ( % SYSTEMROOT%) To katalog, w którym zainstalowany jest system operacyjny Windows. Wspólny zasób Administrator $ Daje administratorom dostęp do tego folderu przez sieć.

Udostępnij FAKS $ używane przez użytkowników do wysyłania faksów. Ten folder buforuje pliki i strony tytułowe znajdujące się na serwerze plików.

Udział IPC $ używany podczas organizowania tymczasowych połączeń utworzonych przez aplikacje do wymiany danych za pomocą nazwanych potoków. Z reguły służy do zdalnego administrowania serwerami w sieci.

Udostępnij PRINT $ służy do zdalnego zarządzania drukarkami.

Jeśli usuniesz ukryte zasoby administracyjne utworzone przez system operacyjny ( np. ADMIN $ lub C $), a następnie po ponownym uruchomieniu komputera lub zrestartowaniu usługi serwera, zostaną one ponownie utworzone. Jeśli usuniesz ukryte zasoby administracyjne utworzone przez użytkowników, to po ponownym uruchomieniu komputera nie zostaną odtworzone. Microsoft Windows XP Home Edition nie tworzy ukrytych udziałów administracyjnych.

Łączenie z udziałami sieciowymi w systemie Windows XP / 2000

Za pomocą standardowego polecenia systemu Windows XP / 2000 można łączyć się z ukrytymi udziałami administracyjnymi i sieciowymi. wykorzystanie netto:

Polecenie użycia netto Służy do łączenia i rozłączania się z zasobami sieci oraz do wyświetlania informacji o bieżących połączeniach z takimi zasobami. Jeśli zasób sieciowy jest bieżącym dyskiem lub jest używany przez działającą aplikację, nie można odłączyć się od takiego zasobu.

Poniżej znajduje się przykład użycia polecenia net use do połączenia ze standardowym udziałem C $, komputer z systemem Windows 2000 o pełnej nazwie Pro2000, zlokalizowany w sieci lokalnej:

Polecenie użycia netto zakończono pomyślnie pod nazwą użytkownika Administrator i pustym hasłem! W większości przypadków po zainstalowaniu systemu Windows hasło do konta o nazwie Administrator, tworzone domyślnie, jest zapomniane lub po prostu nie chce być ustawione, a zdarza się, że podczas instalacji zostało utworzone inne konto administracyjne, a konto o nazwie Administrator zostało utworzone domyślnie pozostawiony bez opieki!

C: \\\u003e cd / d q: Q: \\\u003e dir Wolumin na urządzeniu Q nie ma etykiety. Numer seryjny woluminu: 407D-A72A Zawartość folderu Q: 13/13/2012 08:46 0 AUTOEXEC.BAK 03/13/2012 08:57 Dokumenty i ustawienia 06/17/2012 08:34 Intel 04/01/2012 04:02 MySoft 06/12/2012 11: 35 NC 06/18/2012 10:10 OpenSSL-Win32 06/18/2012 10:08 Pliki programów 06/25/2012 15:48 PUBLIC 05/18/2012 10:53 rms 04/29/2012 10:48 Temp 11/06/2012 10:28 PM WINDOWS 1 pliki 0 bajt 10 folderów 1 919 221 760 bajtów za darmo Q: \\\u003e

Po podłączeniu zasobu C $ i jego powiązanie z literą dysku, zasób C $ będą dostępne w twoim eksploratorze i będzie można z nim pracować tak jak ze zwykłym dyskiem lokalnym, cóż, wtedy wszystko będzie zależeć od twoich umiejętności i wyobraźni ...

UWAGA!!! Udostępnione zasoby będą dostępne tylko wtedy, gdy usługa serwera jest włączona / uruchomiona, a jeśli nie zamierzasz udostępniać swoich zasobów, lepiej nie tylko je zatrzymać, ale całkowicie wyłączyć. Usługa serwera - zapewnia obsługę udostępniania plików, drukarek i nazwanych potoków dla danego komputera za pośrednictwem połączenia sieciowego. Jeśli usługa zostanie zatrzymana, takie funkcje zakończą się niepowodzeniem. Jeśli ta usługa nie zostanie rozwiązana, nie można uruchomić żadnych wyraźnie zależnych usług.

Powyższy przykład wyraźnie pokazuje podatność otwartych zasobów sieciowych. i konto administratora tworzone domyślnie z pustym hasłem! Aby uniknąć powstawania takich luk i w wyniku regularnej ponownej instalacji systemu Windows z kolejną klątwą Billa Gatesa, wystarczy początkowo pokryć, że tak powiem, wszystkie luki i dziury !!!

Wyłączanie / usuwanie udziałów sieciowych

Najłatwiejszym sposobem jest wyłączenie usługi serwera, ale niektóre usługi i programy wymagają jej wsparcia, w takim przypadku wyłączenie usługi serwera nie jest dla nas odpowiednie.

Aby wyłączyć udziały administracyjne i sieciowe ( C $, ADMIN $, FAKS $, IPC $, DRUKUJ $) w systemie Windows XP / 2000 potrzebujesz:

UWAGA! W systemie Windows 2000 nie trzeba dodawać parametru AutoShareWks.

Po ponownym uruchomieniu komputera wszystkie udostępnione zasoby sieciowe zostaną usunięte, z wyjątkiem jednego IPC $, nie można go usunąć:

Specjalny wspólny zasób IPC $

Reprezentuje zasób do udostępniania dostępu do nazwanych potoków, które zapewniają komunikację między programami. Służy do zdalnego administrowania komputerem i przeglądania udostępnionych zasobów komputera. Tego zasobu nie można usunąć.

Aby usługa serwera działała, wymagany jest specjalny udział IPC $ i nie można go usunąć. Aby wyświetlić listę bieżących udziałów sieciowych, użyj polecenia net share.

Powtarzamy, że aby uniknąć powstawania luk we współdzielonych zasobach sieciowych oraz w wyniku regularnej ponownej instalacji systemu Windows z kolejną klątwą Billa Gatesa, wystarczy początkowo pokryć, że tak powiem, wszystkie luki i dziury !!!

Co to jest IPC $? Słyszałem, że możliwe jest zdalne hakowanie? Czy muszę wyłączyć ten zasób, jeśli tak, jak to zrobić?

IPC $, czyli komunikacja między procesami, to specjalny zasób administracyjny do tworzenia nazwanych potoków. Za pośrednictwem tego drugiego komputery wymieniają różne informacje o usługach w Internecie. IPC $ służy również do zdalnego zarządzania serwerem (ryc. 10.1).

Figa. 10.1Włączanie usługi udostępniania sieci IPC $

Aby zdecydować, czy wyłączyć ten zasób, czy nie, należy wziąć pod uwagę następujące kwestie:

¦ jeśli jest to stacja robocza, którą należy kontrolować zdalnie, lepiej nie rozłączać się;

¦ jeśli stacja robocza nie wymaga zdalnej administracji, możesz ją wyłączyć;

¦ jeśli jest to serwer, wówczas odłączanie nie jest w ogóle tego warte, ponieważ nie będzie można uzyskać do niego dostępu przez sieć.

IPC $ jest wyłączany przez CMD za pomocą polecenia net share ipc $ / delete (po ponownym uruchomieniu ten zasób jest nadal włączony sam, więc możesz napisać odpowiedni plik BAT i ustawić go w automatycznym ładowaniu).

Mój komputer jest w sieci lokalnej. Konieczne jest upewnienie się, że maszyna zapewnia zasoby otwarte dla ogólnego dostępu, a jednocześnie aby ukryte zasoby udostępnione C $, D $ itp. Nie były dostępne. Jak to zrobić?

Wszystko, co musisz zrobić, to utworzyć parametr AutoshareWks typu DWORD z wartością zerową w następującej sekcji :.


Co to jest fałszowanie i jak się przed tym zabezpieczyć?

W rzeczywistości fałszowanie jest substytutem. W tym przypadku mamy na myśli fałszowanie adresów IP, czyli fałszowanie adresów IP. Podstawienie, w którym złośliwy użytkownik, korzystający z obcego adresu IP znajdującego się w zaufanej strefie adresów IP lub autoryzowanego adresu zewnętrznego, udaje obiekt, któremu można zaufać. Najczęściej, aby zabezpieczyć się przed fałszowaniem adresów IP, stosowana jest metoda powiązania adresu IP z adresem karty sieciowej (adresem MAC), ale ta metoda jest również niedoskonała: obecnie znane są narzędzia zastępujące obecny adres MAC.

Co to jest wąchanie i czy istnieją specjalne zabezpieczenia przed nim?

W najprostszym przypadku sniffing oznacza przechwytywanie pakietów przez Internet. Mówiąc dokładniej: sniffer wprowadza kartę sieciową (tam, gdzie jest zainstalowana) w tak zwany „tryb niesłyszalny”, dzięki czemu maszyna atakująca przechwytuje wszystkie pakiety sieciowe, nawet te, które nie są do niej przeznaczone. Przykładem sniffera jest Cain & Abel. Jako ochronę podczas budowania sieci lokalnej możesz zalecić użycie przełączników (switch), a nie koncentratorów (hub), a także użycie protokołów, które nie przesyłają danych w przejrzystej formie (SSH, SSL, Kerberos). Ale w tym przypadku możliwe jest przechwytywanie pakietów przy użyciu zaawansowanych technik (na przykład ARP Poizoning).

Co to jest phishing i czy możesz się przed nim uchronić?

Phishing to technika oszukiwania odwiedzających witrynę. Podsumowując: odwiedzający odwiedza witrynę bardzo podobną do oryginalnej, wypełnia kolumny wymagające poufnych informacji (numer karty kredytowej, hasło itp.). Ponadto wszystkie te informacje są wysyłane do atakującego, który utworzył tę fałszywą witrynę. Narzędzia ochrony przed phishingiem można znaleźć w najnowszych wersjach przeglądarek internetowych, a także w pakietach antywirusowych i zaporach ogniowych. Należy jednak pamiętać, że do dziś nie ma skutecznego sposobu ochrony przed phishingiem. Głównym narzędziem ochrony w tym przypadku jest czujność użytkownika.

Wiadomo, że wiele wirusów zastępuje pliki systemowe własnymi. Jak ustalić tę zamianę?

Aby zawsze mieć świadomość takich „sztuczek”, należy włączyć funkcję powiadamiania o ochronie plików. Odbywa się to poprzez wpisanie do rejestru w HKEY_ LOCAL_MACHINE \\ Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Sys-temFileProtection parametru typu DWORD ShowPopups równego 1.

Jak wyczyścić zapamiętane hasła w IE?

Internet Explorer zintegrował dość wygodną rzecz - autouzupełnianie i przechowywanie haseł. Aby usunąć zapisane hasła, wykonaj następujące czynności: w IE przejdź do Narzędzia\u003e Opcje internetowe\u003e Treść\u003e Dane osobowe\u003e Autouzupełnianie,następnie naciśnij przycisk Wyczyść hasła.

Jak mogę ukryć adresy odwiedzanych witryn, które są automatycznie wyświetlane na pasku adresu po wprowadzeniu nowego adresu?

Takie ślady można usunąć, usuwając odpowiednie wpisy rejestru w. Uwaga: zapisywane są tutaj inne ślady, takie jak historia dostępu do zdalnych napędów C $, D $ dla sieci LAN, historia wpisanych w formularzach wyszukiwania itp.

Po sprawdzeniu przez Kaspersky okazało się, że główny rekord rozruchowy został zmieniony w systemie. Co to może być i jak przywrócić początkowy stan rekordu rozruchowego (ryc. 10.2)?




Figa. 10.2Sprawdź rekordy rozruchowe?

Najprawdopodobniej zmodyfikowany bootloader jest konsekwencją wirusa rozruchowego, chociaż możliwe jest, że bootloader się zmienił, a nie z powodu infekcji wirusowej. Możesz przywrócić bootloader z konsoli odzyskiwania: w tym celu musisz uruchomić konsolę odzyskiwania i zarejestrować poprawkę mbr i fix boot boot. Możesz uruchomić się w Konsoli odzyskiwania za pomocą rozruchowego dysku XP, wybierając opcję Napraw instalację systemu Windows XPi ConsoLe © odzyskiwania.Jednak odzyskanie w ten sposób nie jest najlepszym sposobem. W większości przypadków program ładujący nadal się nie odzyskuje. Tylko wyspecjalizowane oprogramowanie może rozwiązać takie problemy, czego żywym przykładem jest ADINF32.


Powiedz mi, gdzie są zarejestrowane aktualizacje w Kaspersky Anti-Virus 7.0. A następnie, gdy ponownie zainstalujesz system, będziesz musiał ponownie pobrać wszystkie aktualizacje.

Aktualizacje - folder bazy danych znajduje się w folderze Set-tings \\ All Users \\ Application Data \\ Kaspersky Lab \\ AVP7 \\ Bases.


Biorąc pod uwagę wyniki licznych testów, możemy powiedzieć, że żadna z istniejących przeglądarek nie jest w 100% bezpieczna. Tymczasem niektóre produkty nadal można uznać za całkiem bezpieczne. Jednym z takich produktów jest Opera.


Sytuacja jest następująca: mój komputer jest w sieci lokalnej i mam dostęp do Internetu za pomocą karty. Limit starej karty został wyczerpany, ale nie ma możliwości wprowadzenia nowej nazwy użytkownika i hasła, ponieważ podczas próby zalogowania się do dowolnej witryny okno uwierzytelniania z serwerem nie pojawia się (wszystkie ustawienia serwera proxy są prawidłowe). Jak zwrócić okno logowania i hasło?

Aby okno uwierzytelniania pojawiło się ponownie, musisz usunąć stary login i hasło poprzez przystawkę. konta użytkowników(Rys. 10.3) - w tym celu przejdź do menu Początek? Biegaćwprowadź polecenie userpasswords2 sterowania komendą, w wyświetlonym oknie kliknij Dodatkowo? Zarządzanie hasłami Usunąć


Podczas ładowania systemu Kaspersky Anti-Virus, który wcześniej działał bezawaryjnie, z jakiegoś powodu przestał się uruchamiać; kiedy próbujesz wymusić start, również się rozłącza. Co to może być i jak sobie z tym poradzić?

Najprawdopodobniej twój system jest zainfekowany wirusem, który wyłącza Kaspersky Anti-Virus. Taka „infekcja” najprawdopodobniej jest skonfigurowana w celu wyłączenia innych popularnych produktów antywirusowych. Wyjściem jest uruchomienie z czystego środowiska, takiego jak dysk rozruchowy (Windows LiveCD). Ponadto, jako opcja, sprawdź system w tym środowisku z antywirusem, który nie wymaga instalacji (taki antywirus można uruchomić z dysku flash, na przykład popularnego produktu Dr.Web CureIt Scanner (ryc. 10.4), który można pobrać z oficjalnej strony Dr.Web) .



Figa. 10.3Zarządzanie hasłami




Figa. 10.4Skaner CureIt w akcji


Sprawdziłem mój dysk twardy w Kaspersky i znalazłem prawdziwego wirusa w dystrybucjach Panda Titanium! Jak być

Najprawdopodobniej plik nie jest niczym zainfekowany i nie należy wywoływać alarmu. Większość programów antywirusowych działa od czasu do czasu podczas skanowania plików innych programów antywirusowych.


Jestem początkującym administratorem systemu i chciałbym poznać Twoją opinię na temat tego, który z systemów operacyjnych serwera można uznać za najbardziej niezawodny i wydajny?


Moja zapora stale zgłasza pakiety przychodzące skądś z flagą „syn”. Co to znaczy?

Najprawdopodobniej ktoś lub coś (na przykład robak sieciowy) skanuje komputer. Skanowanie jest zwykle przygotowaniem do ataku. Dlatego masz coś do przemyślenia.

DZWONEK

Są tacy, którzy czytają te wiadomości przed tobą.
Subskrybuj, aby otrzymywać świeże artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać Dzwon
Bez spamu