Programowanie współbieżne i rozproszone/PWR Ćwiczenia shm: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Mengel (dyskusja | edycje)
Nie podano opisu zmian
 
Mengel (dyskusja | edycje)
Nie podano opisu zmian
Linia 6: Linia 6:


== Scenariusz ==
== Scenariusz ==
Segmenty pamięci dzielonej to trzeci, ostatni już mechanizm z pakietu IPC. Jak zwykle do segmentów pamięci dzielonej stosują się wszystkie uwagi dotyczące mechanizmów IPC, omówione przy okazji kolejek komunikatów.
<!--
W systemie Unix kazdy proces wykonuje sie we wlasnej wirtualnej przestrzeni
adresowej. Przestrzenie roznych procesow sa rozlaczne, co stwarza
problemy ze wspoldzieleniem informacji (nie mozna zdefiniowac
zmiennych "globalnych", ktore bylyby dostepne dla wielu procesow). W
celu rozwiazania tego problemu do pakietu IPC Systemu V dolaczono
mechanizm segmentow pamieci dzielonej.


Segment pamieci dzielonej jest fragmentem pamieci. Zarzadza nim system
=== Wstęp ===
operacyjny. Segment pamieci dzielonej sklada sie z pewnej liczby stron
Segmenty pamięci dzielonej to trzeci, ostatni już mechanizm z pakietu IPC. Jak zwykle do segmentów pamięci dzielonej stosują się wszystkie uwagi dotyczące mechanizmów IPC, omówione przy okazji kolejek komunikatów.  Dotychczas wszystkie programy, które pisaliśmy w środowisku Unix składały się z procesów, z których każdy korzystał z własnych zmiennych. Zmienne współdzielone, dostępne dla wielu procesów nie występowały, a synchronizacja odbywała się poprzez wymianę komunikatów bądź to za pomocą łączy bądź kolejek komunikatów. Pewne odstępstwo od tej zasady nastąpiło z chwilą wprowadzenia semaforów, ale ponieważ to system dba o zarządzanie nimi i przydzielenie im miejsca w pamięci, więc programista nie musiał się tym zajmować. Dziś chcemy korzystać ze wspólnej pamięci w postaci zmiennych dostępnych dla wielu procesów.
(a zatem jego rozmiar jest zawsze wielokrotnoscia rozmiaru
 
stronu). Segment pamieci dzielonej moze na zadanie procesu byc
Choć procesy uniksowe uruchamiane na tym samym komputerze wykonują się we wspólnej pamięci, to jednak z logicznego punktu widzenia przestrzenie adresowe różnych procesów są rozłączne. Aby umożliwić korzystanie na przykład ze wspólnych zmiennych wprowadzono, początkowo do Uniksa Systemu V,  a później już do wszystkich wersji systemu, mechanizm segmentow pamieci dzielonej.
przylaczony pod wskazany lub wybrany przez system operacyjny (to
 
drugie rozwiazanie jest preferowane) adres wirtualny procesu. Jesli
Segment pamięci dzielonej jest fragmentem pamięci, który może być ''podpinany'' do przestrzeni adresowych różnych procesów. Zarządzaniem segmentami pamięci dzielonej zajmuje się system, ale to programista jest odpowiedzialny za utworzenie segmentu o potrzebnej mu wielkości oraz jego podpięcie pod pewien adres przestrzeni adresowej (najczęściej wybrany przez system operacyjny). Jeśli ten sam segment zostanie przyłączony do przestrzeni adresowych różnych procesów, to wszelkie dane (a więc zmienne) w nim przechowywanie stają się widoczne i dostępne dla tych procesów. Oczywiście dostęp do nich wymaga wówczas synchronizacji, ale mamy już do tego odpowiednie mechanizmy --- na przykład semafory.  
zatem dwa procesy przylacza ten sam segment do wlasnych przestrzeni
adresowych to wszystkie dane znajdujace sie w tym segmencie staja sie
dostepne dla obydwu procesow. W ten sposob uzyskuje sie wspoldzielenie
danych.
Po przylaczeniu segmentu do pamieci wirtualnej procesu dostep do
danych znajdujacych sie w nim odbywa sie za pomoca zwyklych operacji
dostepu do pamieci. Daje to duza wydajnosc tego mechanizmu
komunikacji. Niestety te zyski ze stosowania pamieci dzielonej sa
czesto rownowazone przez narzut zwiazany z koniecznosci synchronizacji
dostepu do danych wspoldzielonych (najczesciej za pomoca semaforow).


Gdy segement pamieci staje sie juz niepotrzebny w danym procesie
Operacje zapisu i odczytu z segmentu pamięci wirtualnej do zwykłe operacje dostępu do pamięci. Dzięki temu są one realizowane szybko i wydajnie, znacznie szybciej niż na przykład wysłanie komunikatu za pomocą kolejki komunikatów, które wymaga kopiowania komunikatu między przestrzenią adresową nadawcy, jądra oraz odbiorcy. Tutaj występuje zapis po stronie nadawcy i odczyt po stronie odbiorcy.  
nalezy go odlaczyc od przestrzeni adresowej procesu. Po odlaczeniu
system operacyjny w dalszym ciagu przechowuje segment i dane w nim
zapisane (nawet, jesli segment nie jest juz przylaczony do zadnego
procesu). Gdy segment staje sie juz niepotrzebny nalezy go usunac.


Podstawowe funkcje systemowe przeznaczone do obslugi segmentow pamieci
Ponieważ segment pamięci jest zasobem IPC, trzeba go najpierw utworzyć lub uzyskać dostęp do segmentu już istniejącego. Identyfikacja segmentów odbywa się jak zwykle za pomocą ustalonego klucza, a następnie identyfikatora przekazywanego przez funkcję <tt>get</tt>, która w przypadku segmentów pamięci dzielonej nazywa się <tt>shmget</tt>. Ale to jeszcze nie koniec. Aby proces mógł coś zapisać do segmentu lub z niego odczytać, segment musi zostać podpięty do przestrzeni adresowej. Podobnie, gdy segment staje się niepotrzebny w danym procesie należy go odłączyc od przestrzeni adresowej. Dopóki jednak segment jest przyłączony do jakiekolwiek procesu, dane w nim zapisywane są utrzymywane. Segment, który jest już niepotrzebny w żadnym procesie należy usunąć, jak każdy zasób IPC.
dzielonej to:
  - shmget - utworzenie segmentu pamieci dzielonej
            (uzyskanie dostepu do istniejacego segmentu)
  - shmat  - przylaczenie segmentu pamieci dzielonej
  - shmdt  - odlaczenie segmentu pamieci dzielonej
  - shmctl - operacje administracyjne na segmencie pamieci dzielonej


Program w C korzystajacy z mechanizmu pamieci dzielonej musi dolaczyc do
Tak wygląda typowy scenariusz pracy z segmentami pamięci dzielonej. Do jego realizacji służą następujące funkcje systemowe:
programu pliki naglowkowe:
* shmget --- tworząca  segment pamięci dzielonej
* shmat --- przyłączająca segmentu pamięci dzielonej do przestrzeni adresowej procesu
* shmdt  --- odlączająca segmentu pamięci dzielonej od przestrzeni adresowej procesu
* shmctl --- realizująca operacje sterujące na segmencie pamięci dzielonej


Program w C wykorzystujący mechanizm pamięci dzielonej musi wykorzystać następujące pliki nagłówkowe:
<Source>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/shm.h>
</Source>


1.1. Utworzenie (uzyskanie dostepu do) segmentu pamieci dzielonej
=== Tworzenie (uzyskanie dostępu do) segmentu pamięci dzielonej ===
-----------------------------------------------------------------
 
Operacja ta przypomina analogiczne operacje wykonywane na kolejkach
komunikatow i zestawach semaforow.
 
Utworzenie (lub uzyskanie dostepu do juz istniejacego zestawu)
realizuje funkcja systemowa shmget:


Do utworzenia segmentu pamięci dzielonej służy funkcja systemowa <tt>shmget</tt>:
<Source>
     int shmget (key_t klucz, int rozmiar, int flagi)
     int shmget (key_t klucz, int rozmiar, int flagi)
Funkcja shmget pobiera klucz, ktory powinien byc dluga liczba calkowita
</Source>
i przekazuje identyfikator segmentu pamieci dzielonej
* Pierwszym parametrem tej funkcji jest jak zwykle klucz zasobu
(albo -1 w przypadku bledu).
* Trzecim parametrem są opcje, które jak zwykle określają prawa dostępu do pamięci oraz ewentualne opcje <tt>IPC_CREAT</tt>, <tt>IPC_EXCL</tt> lub <tt>IPC_PRIVATE</tt>
* Wynikiem funkcji <tt>shmget</tt> jest identyfikator segmentu pamięci dzielonej lub -1 w przypadku błędu
Parametrem specyficznym dla segmentów pamięci dzielonej jest <tt>rozmiar</tt>, który określa rozmiar tworzonego segmentu pamięci dzielonej. Ma on znaczenie jedynie wtedy, gdy segment jest faktycznie tworzony. Jeśli funkcja powoduje jedynie uzyskanie dostępu do już istniejącego segmentu, to  parametr ten jest ignorowany. Tak naprawdę, utworzony segment będzie miał będzie składał się z pewnej (odpowiednio dużej) liczby stron, więc jego rozmiar jest zawsze wielokrotnością rozmiaru strony.


Klucz pelni role 'nazwy' segmentu. Procesy, ktore chca
=== Przyłączanie segmentu pamięci dzielonej ===
korzystac z tego samego segmentu musza go utworzyc/otworzyc
podajac ten sam klucz.


Parametr 'rozmiar' okresla rozmiar tworzonego segmentu pamieci
<!--
dzielonej i jest istotny tylko wowczas, gdy funkcja faktycznie tworzy
nowy segment. Nalezy pamietac, ze rzeczywisty rozmiar segmentu bedzie
najmniejsza wielokrotnoscia rozmiaru strony wieksza od wskazanego
rozmiaru.
 
Parametr 'flagi' (por. opis funkcji msgget) sluzy do okreslenia:
  - praw dostepu do zestawu semaforow (analogicznie do praw dostepu do
      plikow),
  - sposobu otwarcia zestawu semaforow:
        IPC_CREAT - polecenie utworzenia zestawu semaforow
        IPC_CREAT | IPC_EXCL - utworzenie nieistniejacego zestawu
                    (porazka jesli zestaw o danym kluczu juz istnieje)
 
Jest mozliwa specjalna wartosc IPC_PRIVATE parametru 'klucz'
(por. opis funkcji msgget).
 
*********************************
Przeczytaj man do funkcji shmget
*********************************
 
1.2. Przylaczanie segmentu pamieci dzielonej
--------------------------------------------


Aby proces mogl skorzystac z segmentu pamieci dzielonej musi:
Aby proces mogl skorzystac z segmentu pamieci dzielonej musi:

Wersja z 12:05, 17 paź 2006

Tematyka zajęć

Segmenty pamięci dzielonej

Literatura

Scenariusz

Wstęp

Segmenty pamięci dzielonej to trzeci, ostatni już mechanizm z pakietu IPC. Jak zwykle do segmentów pamięci dzielonej stosują się wszystkie uwagi dotyczące mechanizmów IPC, omówione przy okazji kolejek komunikatów. Dotychczas wszystkie programy, które pisaliśmy w środowisku Unix składały się z procesów, z których każdy korzystał z własnych zmiennych. Zmienne współdzielone, dostępne dla wielu procesów nie występowały, a synchronizacja odbywała się poprzez wymianę komunikatów bądź to za pomocą łączy bądź kolejek komunikatów. Pewne odstępstwo od tej zasady nastąpiło z chwilą wprowadzenia semaforów, ale ponieważ to system dba o zarządzanie nimi i przydzielenie im miejsca w pamięci, więc programista nie musiał się tym zajmować. Dziś chcemy korzystać ze wspólnej pamięci w postaci zmiennych dostępnych dla wielu procesów.

Choć procesy uniksowe uruchamiane na tym samym komputerze wykonują się we wspólnej pamięci, to jednak z logicznego punktu widzenia przestrzenie adresowe różnych procesów są rozłączne. Aby umożliwić korzystanie na przykład ze wspólnych zmiennych wprowadzono, początkowo do Uniksa Systemu V, a później już do wszystkich wersji systemu, mechanizm segmentow pamieci dzielonej.

Segment pamięci dzielonej jest fragmentem pamięci, który może być podpinany do przestrzeni adresowych różnych procesów. Zarządzaniem segmentami pamięci dzielonej zajmuje się system, ale to programista jest odpowiedzialny za utworzenie segmentu o potrzebnej mu wielkości oraz jego podpięcie pod pewien adres przestrzeni adresowej (najczęściej wybrany przez system operacyjny). Jeśli ten sam segment zostanie przyłączony do przestrzeni adresowych różnych procesów, to wszelkie dane (a więc zmienne) w nim przechowywanie stają się widoczne i dostępne dla tych procesów. Oczywiście dostęp do nich wymaga wówczas synchronizacji, ale mamy już do tego odpowiednie mechanizmy --- na przykład semafory.

Operacje zapisu i odczytu z segmentu pamięci wirtualnej do zwykłe operacje dostępu do pamięci. Dzięki temu są one realizowane szybko i wydajnie, znacznie szybciej niż na przykład wysłanie komunikatu za pomocą kolejki komunikatów, które wymaga kopiowania komunikatu między przestrzenią adresową nadawcy, jądra oraz odbiorcy. Tutaj występuje zapis po stronie nadawcy i odczyt po stronie odbiorcy.

Ponieważ segment pamięci jest zasobem IPC, trzeba go najpierw utworzyć lub uzyskać dostęp do segmentu już istniejącego. Identyfikacja segmentów odbywa się jak zwykle za pomocą ustalonego klucza, a następnie identyfikatora przekazywanego przez funkcję get, która w przypadku segmentów pamięci dzielonej nazywa się shmget. Ale to jeszcze nie koniec. Aby proces mógł coś zapisać do segmentu lub z niego odczytać, segment musi zostać podpięty do przestrzeni adresowej. Podobnie, gdy segment staje się niepotrzebny w danym procesie należy go odłączyc od przestrzeni adresowej. Dopóki jednak segment jest przyłączony do jakiekolwiek procesu, dane w nim zapisywane są utrzymywane. Segment, który jest już niepotrzebny w żadnym procesie należy usunąć, jak każdy zasób IPC.

Tak wygląda typowy scenariusz pracy z segmentami pamięci dzielonej. Do jego realizacji służą następujące funkcje systemowe:

  • shmget --- tworząca segment pamięci dzielonej
  • shmat --- przyłączająca segmentu pamięci dzielonej do przestrzeni adresowej procesu
  • shmdt --- odlączająca segmentu pamięci dzielonej od przestrzeni adresowej procesu
  • shmctl --- realizująca operacje sterujące na segmencie pamięci dzielonej

Program w C wykorzystujący mechanizm pamięci dzielonej musi wykorzystać następujące pliki nagłówkowe:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

Tworzenie (uzyskanie dostępu do) segmentu pamięci dzielonej

Do utworzenia segmentu pamięci dzielonej służy funkcja systemowa shmget:

     int shmget (key_t klucz, int rozmiar, int flagi)
  • Pierwszym parametrem tej funkcji jest jak zwykle klucz zasobu
  • Trzecim parametrem są opcje, które jak zwykle określają prawa dostępu do pamięci oraz ewentualne opcje IPC_CREAT, IPC_EXCL lub IPC_PRIVATE
  • Wynikiem funkcji shmget jest identyfikator segmentu pamięci dzielonej lub -1 w przypadku błędu

Parametrem specyficznym dla segmentów pamięci dzielonej jest rozmiar, który określa rozmiar tworzonego segmentu pamięci dzielonej. Ma on znaczenie jedynie wtedy, gdy segment jest faktycznie tworzony. Jeśli funkcja powoduje jedynie uzyskanie dostępu do już istniejącego segmentu, to parametr ten jest ignorowany. Tak naprawdę, utworzony segment będzie miał będzie składał się z pewnej (odpowiednio dużej) liczby stron, więc jego rozmiar jest zawsze wielokrotnością rozmiaru strony.

Przyłączanie segmentu pamięci dzielonej