Wariacje kombinacje permutacje C++

W tym post-cie, opiszę teoretyczne zagadnienie z matematyki dyskretnej (kombinatoryki) jak: wariacje, kombinacje i permutacje.
Zamieszam również gotowe programy i kody źródłowe tych programów napisane w C++ Builder 2010 obliczające wariacje z powtórzeniami, wariacje bez powtórzeń, kombinacje bez powtórzeń, kombinacje z powtórzeniami i permutacje.
Zamieszczam również gotowe programy i kody źródłowe dla środowiska programistycznego C++ Builder 6.0.
W kodach źródłowych zamieszczone są dokładne opisy algorytmów dla: wariacji z powtórzeniami, wariacji bez powtórzeń, kombinacji bez powtórzeń, kombinacji z powtórzeniami i permutacji.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002.
Stanowi doskonałe teoretyczne i praktyczne uzupełnienie wiedzy dla studentów kierunku informatyka i matematyka.


Zaczynamy!

1. Wariacje z powtórzeniami:

Wariacje z powtórzeniami to ciągi długości k o elementach ze zbioru X.
k- elemenowych wariacji z powtórzeniami ze zbioru n- elementowego jest:
n*n*n*...*n=n^k (n do potęgi k)
Uwaga - Istotna jest kolejność wylosowanych liczb, elementy mogą się powtarzać.


Pliki do pobrania:
1. Wariacje z powtórzeniami C++ Builder 2010 (exe i kody źródłowe) (UNICODE)
-pobierz
2. Wariacje z powtórzeniami C++ Builder 6.0 (exe i kody źródłowe)
-pobierz


2. Wariacje bez powtórzeń:

Wariacje bez powtórzeń to ciągi długości k o elementach ze zbioru X, ale każdy element występuje co najwyżej raz.
k- elemenowych wariacji bez powtórzeń ze zbioru n- elementowego jest:
n*(n-1)*(n-2)*...*(n-k+1)=n!/(n-k)!
Uwaga - Istotna jest kolejność wylosowanych liczb, elementy nie mogą się powtarzać.


Pliki do pobrania:
1. Wariacje bez powtórzeń C++ Builder 2010 (exe i kody źródłowe) (UNICODE)
-pobierz
2. Wariacje bez powtórzeń C++ Builder 6.0 (exe i kody źródłowe)
-pobierz


3. Kombinacje bez powtórzeń:

Kombinacje bez powtórzeń to podzbiory długości k o elementach ze zbioru X, ale każdy element występuje co najwyżej raz i nie jest istotna kolejność wylosowanych liczb.
k- elemenowych kombinacji bez powtórzeń ze zbioru n- elementowego jest:
n!/k!*(n-k)!
Uwaga - Nie jest istotna kolejność wylosowanych liczb, elementy nie mogą się powtarzać.


Pliki do pobrania:
1. Kombinacje bez powtórzeń C++ Builder 2010 (exe i kody źródłowe) (UNICODE)
-pobierz
2. Kombinacje bez powtórzeń C++ Builder 6.0 (exe i kody źródłowe)
-pobierz


4. Kombinacje z powtórzeniami:

Kombinacje z powtórzeniami to podzbiory długości k o elementach ze zbioru X, nie jest istotna kolejność wylosowanych liczb, ale elementy mogą się powtarzać.
k- elemenowych kombinacji bez powtórzeń ze zbioru n- elementowego jest:
(k+n-1)!/k*(n-1)!
Uwaga - Nie jest istotna kolejność wylosowanych liczb, elementy mogą się powtarzać.


Pliki do pobrania:
1. Kombinacje z powtórzeniami C++ Builder 2010 (exe i kody źródłowe) (UNICODE)
-pobierz
2. Kombinacje z powtórzeniami C++ Builder 6.0 (exe i kody źródłowe)
-pobierz


5. Permutacje:

Szczególnym przypadkiem wariacji bez powtórzeń, gdy k=n są permutacje.
n- elemenowych permutacji jest:
n*(n-1)*(n-2)*...*2*1=n!

Pliki do pobrania:
1. Permutacje C++ Builder 2010 (exe i kody źródłowe) (UNICODE)
-pobierz
2. Permutacje C++ Builder 6.0 (exe i kody źródłowe)
-pobierz



UNIX, Linux procesy - kurs

W tym post-cie, opiszę teoretycznie jądo systemu UNIX.
Jest to piąta część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach zajmę się systemem operacyjnym Windows.
W części pierwszej opisałem: wstęp do UNIX-a.
W części drugiej opisałem: system plików UNIX-a.
W części trzeciej opisałem: powłokę UNIX-a.
W części czwartej opisałem: jądro UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



Tworzenie, usuwanie i zawieszanie procesów. Proces może utworzyć nowy proces, za pomocą funkcji systemowej fork. Jej wykonanie polega na rozwidleniu procesu wydającego to zlecenie na dwa procesy: macierzysty i potomny które mogą od tej pory pracować współbieżnie, niezależnie od siebie. Dla procesu potomnego jest inicjalizowany oddzielny obszar pamięci operacyjnej. W języku C zlecenie utworzenia nowego procesu możemy zapisać następująco pid=fork(). Zwykle, kiedy proces jest tworzony, ma on wykonywać program różny od wykonywanego przez jego proces macierzysty. Rodzina funkcji systemowych exec (plik, arg1,...,argn) umożliwia procesowi wykonywanie kodu zawartego we wskazanym pliku, przy czym plik ten zawiera polecenia UNIX-a lub program w postaci binarnej, natomiast arg1,...,argn są wartościami parametrów tego polecenia. Jego realizacja polega na wprowadzeniu w obszar pamięci operacyjnej procesu nowego kodu i danych. Następną instrukcją procesu jest wówczas pierwsza instrukcja wczytanego kodu. Tak więc proces potomny mający wykonać program np. alfa powinien wykonać zlecenie exec. Oczywiście nie może być ono wydane z procesu macierzystego. Rozwidlenie procesów (przy użyciu funkcji systemowej fork):

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 106.]

Funkcja systemowa wait jest zwykle używana do synchronizacji wykonywania procesu macierzystego i procesu potomnego i okazuje się szczególnie użyteczna, gdy oba procesy mają dostęp do tych samych plików. Mianowicie proces może zawiesić swoje działanie, dopóki któryś z jego procesów potomnych nie zakończy się. Należy w tym celu wykorzystać funkcję systemową wait, na przykład w następujący sposób: pid=wait(&status). Proces może zakończyć swoje działanie operacją exit(status). Powoduje ona zakończenie wykonywania procesu, zamknięcie plików i skasowanie obrazu pamięci procesu.


UNIX, Linux jądro - kurs

W tym post-cie, opiszę teoretycznie jądo systemu UNIX.
Jest to czwarta część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach opiszę: funkcje systemowe związane z procesami na bazie UNIX-a.
W części pierwszej opisałem: wstęp do UNIX-a.
W części drugiej opisałem: system plików UNIX-a.
W części trzeciej opisałem: powłokę UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis jądra systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



Jądro jest najgłębszą częścią systemu operacyjnego UNIX. Działanie systemu operacyjnego w obrębie jądra dzielimy na: - obsługę funkcji systemowych, pułapek i przerwań. W jądrze możemy wyróżnić dwie części: jedna z nich obsługuje zastosowania, a druga przerwania. Struktura jądra - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 95.]

Obie części jądra współpracują w rozdziale zasobów systemu oraz realizacji operacji I/O. Część obsługująca zastosowania rozpoczyna operacje I/O. Rezygnuje z procesora i następnie czeka na powiadomienie przez drugą część, że obsługa I/O została zakończona.
Funkcje systemowe, pułapki i przerwania. Jednym z działań najczęściej wykonywanych w jądrze jest żądanie wykonania funkcji systemowej. Funkcje systemowe zapewniają dostęp do usług świadczących przez jądro, a żądanie ich wykonania można uważać za polecenia dla jądra. Program obsługujący wywołania funkcji systemowej, zanim funkcja systemowa zostanie zainicjowana wykonuje następujące działania wstępne: - odczytuje parametry funkcji systemowej, - sprawdza czy parametry są umieszczone pod poprawnymi adresami i następnie kopiuje je z procesu użytkownika do jądra, - wywołuje w jądrze odpowiedni program obsługujący f. systemową. Wyniki działania funkcji systemowej są zwracane do procesu użytkownika. W przypadku sukcesu program obsługi funkcji systemowej w jądrze zwraca wartość specyficzną dla danej funkcji, w przypadku porażki - wartość -1. W czasie wykonywania funkcji systemowych mogą wystąpić dwa zdarzenia. Do procesu może być wysłany sygnał albo inny proces może osiągnąć wyższy priorytet. Jeżeli do procesu zostanie wysłany sygnał, to może on spowodować zaniechanie funkcji systemowej. Inna możliwość to zawieszenie sygnału do czasu zakończenia funkcji. Jeżeli w systemie istnieje proces o wyższym priorytecie, to program korygujący wywołuje program szeregujący procesy, czyli program obsługujący przydział procesora do procesów. Program ten spowoduje, że procesor zostanie przydzielony do procesu o wyższym priorytecie. Pułapki mogą występować z powodu błędu w programach (na przykład dzielenie przez zero), czy też błędów systemowych (na przykład błąd strony). Proces jest informowany o powstałym problemie albo za pomocą sygnału, albo przez sam fakt swojego zakończenia. Przerwania spowodowane przez urządzenia wejścia/wyjścia są obsługiwane przez moduły obsługi urządzeń (device drivers). Moduły te są włączane do jądra podczas instalacji lub rozbudowy systemu. Programy spowodowane przez inne urządzenia są obsługiwane przez programy przerwań stanowiące standardową część jądra. Przerwania spowodowane przez urządzenia występują asynchronicznie. Programy obsługi urządzeń są uruchamiane na żądanie. Kiedy występuje przerwanie moduł obsługi urządzenia odwołuje się do tzw. stosu przerwań, znajdującego się w części stosu - jądra danego procesu. Program obsługi przerwań musi być wykonany do końca, to znaczy jego wykonanie nie może być przerwane.
Zarządzanie procesami - w systemie UNIX rozróżniamy dwa typy procesów: jądra i użytkowe. Procesy jądra funkcjonują tylko całkowicie wewnątrz jądra. Procesy użytkowe to wszystkie pozostałe procesy, tzn. utworzony przez proces systemowy init i wszystkie procesy z niego wyprowadzane. Proces init wykonuje funkcje administracyjne w systemie, obejmuje obsługę prawidłowego przejścia systemu z trybu jednego użytkownika do trybu wielodostępnego i utworzenie procesu rejestracji (getty) użytkowników. Przejście do trybu wielodostępnego odbywa się zgodnie ze skryptem /etc./rc i obejmuje następujące czynności: - usunięcie plików tymczasowych, ustawienie daty, sprawdzenie systemu plików oraz zainicjowanie programów szeregujących operacje wydruku, a także programów prowadzących księgowości systemu i regulowanie zapisywania bloków buforowanych wewnętrznie przez system na dysk. Podstawą uruchomienia procesu w systemie jest umieszczenie go w pamięci operacyjnej oraz przydzielenie mu procesora. Unix, tak jak każdy system wielozadaniowy stwarza iluzję współbieżnie wykonywania wielu procesów. Jądro systemu określa porządek przydziału zasobów do procesów gotowych do wykonania - mówi o szeregowaniu zasobów systemu. Jądro wykonuje również szeregowanie procesów, tzn. dokonuje ustalenia kolejności, w jakiej procesor ma być przydzielony do procesów gotowych do wykonania. System UNIX wykorzystuje algorytm Round Robin do szeregowania procesów, jednak kwant czasu jest dużo mniejszy niż w standardowej wersji tego algorytmu. Każdy proces ma określony priorytet, przy czym obowiązuje zasada: im większa liczba, tym niższy priorytet. Procesy systemowe wykonujące operacje wejścia/wyjścia oraz inne ważne zadania systemowe mają priorytety o wartościach ujemnych i nie mogą być usunięte przez sygnały. Zwyczajne procesy użytkowników mają priorytety dodatnie, tak więc nie mogą być wykonywane przed systemowymi. Stosowany w systemie UNIX algorytm szeregowania to wielokolejkowy algorytm priorytetowy. Algorytm szeregowania w systemie UNIX - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 98.]

Im więcej czasu procesora dany proces zużywa, tym niższy staje się jego priorytet. We współczesnych systemach kwant czasu procesora przydzielany procesowi to najczęściej 0,1 sekundy (4.3 BSD UNIX), natomiast co sekundę system przelicza na nowo wartość priorytetów, według następującej reguły: nowy priorytet = wartość bazowa + wykorzystanie procesora. Licznik wykorzystania procesora jest zwiększany o 1 z każdym taktem zegara systemowego i jest przechowywany w tak zwanej tablicy procesu. Przekroczenie określonej wartości powoduje przesunięcie procesu do kolejki o niższym priorytecie. Wartość bazowa jest zazwyczaj równa zero. Użytkownik, który pragnie obniżyć priorytet swoich procesów, może ę wartość zwiększyć wykonując funkcje systemową nice. Tylko administrator systemu może obniżyć wartość bazową zwiększając tym samym priorytet swoich procesów. W ramach określonej kolejki do szeregowania procesów jest wykorzystywany algorytm Round Robin. Współpracuje on z systemową procedurą timeout, która przekazuje modułowi obsługi przerwań zegara informację o tym, że upłynął określony kwant czasu. Odpowiednia procedura jądra dokonuje przeszeregowania procesów. Proces traci przydział procesora, gdy skończy się kwant czasu lub gdy oczekuje na zakończenie operacji I/O. Proces może również zrezygnować z przydziału procesora w efekcie zajścia określonego zdarzenia (event). Każdy użytkownik jest identyfikowany przez liczbę całkowitą zwaną identyfikatorem użytkownika (user identification (uid)). Identyfikator przydzielony jest użytkownikowi przez administratora systemu i może znaleźć go w wierszu odpowiadającym nazwie danego użytkownika w pliku /etc./passwd. Każdy proces ma automatycznie przydzielony identyfikator użytkownika który go utworzył. Użytkownik z identyfikatorem równym zero jest użytkownikiem specjalnym zwanym użytkownikiem nadrzędnym (root user albo superuser) albo administratorem systemu. Może on odczytywać i zapisywać wszystkie pliki w systemie, niezależnie od ich właściciela i ich zabezpieczenia. Procesy z identyfikatorem uid równym zero mają możliwość wykonania niewielkiej liczby chronionych funkcji systemowych niedostępnych dla zwykłych użytkowników. Niektóre programy realizujące określone polecenia powinny być dostępne nie tylko administratorowi, ale również zwykłym użytkownikom systemu. Ponieważ ze względu na wymogi bezpieczeństwa systemu, administrator nie może udostępniać hasła do sytemu innym użytkownikom, wprowadzono mechanizm umożliwiający te programy. Mechanizm ten polega na zastąpieniu niektórych bitów określających prawa dostępu do pliku zawierającego program realizujący dane polecenie przez tak zwane bity SETUID. Bity te oznaczone przez s, zastępują wybrane bity x zezwalające na wykonanie programu, a ich obecność oznacza, że efektywnym identyfikatorem użytkownika danego procesu nie jest identyfikator użytkownika który ten proces uruchomił, ale id. użytkownika który jest właścicielem pliku zawierającego wykonywany program. W ten sposób administrator systemu umożliwia w kontrolowany sposób dostęp zwykłym użytkownikom do pewnych informacji o systemie.
Każdy proces dysponuje wydzielonym obszarem pamięci, w którym zawarta jest jego wirtualna przestrzeń adresowa oraz obszary pomocnicze, z których korzysta jądro do zarządzania pracą procesów. W wirtualnej przestrzeni adresowej procesu wyróżnia się cztery segmenty: - segment tekstu programu, - segment danych, - segment stosu, - szczelinę. Segment tekstu programu rozpoczyna się od adresu 0 w wirtualnej przestrzeni adresowej. W segmencie tym nie można niczego zapisywać, można go tylko odczytać. Jest to dzielony między różne procesy wykonujące ten sam kod. W drugim segmencie znajdującym się za tekstem programu, mieszczą się dane użytkownika. W tym obszarze proces może je zarówno zapisywać, jak i odczytywać. W trzecim segmencie pamięci przechowuje się stos. Rozpoczyna się od największego adresu w pamięci wirtualnej procesu. Jeśli stos próbuje przekroczyć granicę segmentu stosu, pojawia się przerwanie sprzętowe. Odpowiednie procedury jądra systemu powiększają rozmiar segmentu stosu  obniżając jego granicę o kilka tysięcy bajtów (najczęściej o rozmiar strony). Programy nie mają możliwości zmiany rozmiaru segmentu stosu. Gdy program rozpoczyna pracę na stos są wpisywane zmienne charakteryzujące środowisko pracy programu oraz samo polecenie i jego argumenty. Obraz procesu w pamięci operacyjnej - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 100.]

Zazwyczaj segment danych i stosu danego programu współdzielą tę samą przestrzeń adresową, lecz rozrastają się niezależnie w przeciwnych kierunkach. Pomiędzy nimi znajduje się obszar nie wykorzystanej przestrzeni, tzw. szczelina. Segment stosu rozrasta się automatycznie, natomiast "ekspansja" segmentu danych jest wykonana z wykorzystaniem funkcji systemowej brk. Jeśli kilku użytkowników wykorzystuje w danej chwili ten sam program, to w pamięci operacyjnej jest przechowywana tylko jedna kopia programu, a nie kilka (po jednej dla każdego użytkownika), jak to się zdarza w innych systemach. Jest to możliwe dzięki mechanizmowi współdzielonego segmentu tekstu programu. Wirtualna przestrzeń adresowa procesów i pamięć fizyczna - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 101.]

Nad wirtualną przestrzenią adresową procesu znajduje się tzw. obszar użytkownika, zawierający informację o stanie procesu. Są to unikalne identyfikatory związane z procesem, informacje o prawach i przywilejach związanych z procesem, obszar ten zawiera również wszystkie deskryptory związane z procesem. Obszar ten może czasami być podzielony na: - strukturę użytkownika która przechowuje informacje o procesie potrzebna tylko wtedy, gdy znajduje się on w p.o. Przechowywany jest tutaj identyfikator użytkownika, który uruchomił proces oraz identyfikator jego grupy. Pamiętany jest tutaj również katalog bieżący i tablica otwartych plików procesu. - blok kontrolny. Informację o procesie dopełniają wektory środowiskowe i argumenty procesu, zawierające wartości parametrów funkcji systemowych i wartości zwracane przez te funkcje. Ogólnie procesy są wykonywane w dwóch trybach: jądra i użytkownika. Wspomniane procesy jądra są wykonywane tylko w trybie jądra natomiast procesy użytkownika mogą być wykonywane w trybie użytkownika i w trybie jądra. Procesy użytkownika mają dostęp do większości usług jądra za pomocą funkcji systemowych. Wywołanie przez proces użytkownika funkcji systemowej powoduje uruchomienie procesu systemowego lub inaczej procesu jądra, który obsługuje wykonanie tej funkcji. Proces jądra wykorzystuje stos różny od stosu procesu użytkownika. Stos jądra (kernel stack) znajduje się zaraz za strukturą użytkownika. Stos jądra i struktura użytkownika tworzą razem systemowy segment danych. Do zarządzania procesami jądro wykorzystuje różnego rodzaju bloki kontrolne. Kiedy proces wykonywany w trybie użytkownika żąda zasobów od systemu operacyjnego za pomocą funkcji systemowej, to następuje zamiana jego trybu na tryb jądra. Każdy tryb pracy wymaga dostępu do różnych zasobów. Zasoby te tworzą kontekst procesu. Zasobami tymi mogą być: - na poziomie użytkownika: zawartość przestrzeni adresowej i jego środowisko uruchomieniowe, - na poziomie jądra: oprócz wyżej wymienionych, parametry szeregowania (np. priorytet procesu) i parametry sterowania zasobami. Użytkownik może tworzyć procesy, sterować ich wykonywaniem i odbierać informację o zmianie statusu wykonywania. Każdy proces ma przydzieloną unikalną wartość, zwaną identyfikatorem procesu (PID). Wartość ta jest używana przez jądro do identyfikacji procesu oraz użytkownika do wywoływania funkcji systemowej. Jądro tworzy proces przez powielenie kontekstu innego procesu. Ten nowy proces zwany jest procesem potomnym oryginalnego procesu macierzystego z identyfikatorem PPID. Kontekst powielony przy tworzeniu procesu zawiera zarówno stan wykonywania procesu na poziomie użytkownika jak i jądra. Współistnienie procesów można zilustrować na przykładzie procesu powłoki, interpretującego polecenia użytkownika. Proces ten w chwili odczytania polecenia z klawiatury tworzy proces potomny odpowiedzialny za realizację tego polecenia. Standardowo proces macierzysty (czyli powłoka) oczekuje na zakończenie procesu potomnego i dopiero wówczas pobiera kolejne polecenia. Użytkownik może spowodować aby dane polecenie było wykonywane w tle. Wtedy proces powłoki nie czekając na zakończenie danego procesu potomnego, pobiera nowe polecenie i tworzy dla niego nowy proces.
Zarządzanie urządzeniami wejścia/wyjścia - w systemie UNIX, tak jak w wielu systemach operacyjnych, szczegóły urządzeń fizycznych są ukryte przed użytkownikiem. Jednakże rozwiązanie zastosowane w tym systemie jest unikalne. Zadanie ukrycia wspomnianych szczegółów należy do jądra - a ściślej do systemu zarządzania urządzeniami wejścia/wyjścia. Jak wiemy, w systemie UNIX wprowadzono zasadę, że urządzenia fizyczne są postrzegane przez użytkownika jako pliki. Osiągnięto to definiując urządzenie wirtualne funkcjonalnie odpowiadające dyskowi i pisząc specjalne programy obsługi urządzeń (device drivers), odwzorowujące operacje urządzenia wirtualnego w operacje urządzenia fizycznego. Ze względu na konieczność specjalnego traktowania przez system wspomnianych plików odpowiadających urządzeniom nazwano je plikami specjalnymi. Istnieją dwa podstawowe typy plików specjalnych: blokowe i znakowe. Pliki blokowe reprezentujące urządzenia blokowe, czyli dyski i taśmy. Pliki znakowe reprezentujące urządzenia znakowe, czyli terminale i drukarki. System wejścia/wyjścia składa się ze zbioru modułów obsługi urządzeń, zazwyczaj jednego modułu obsługi na urządzenie określonego typu. Moduły te są dołączane do sytemu operacyjnego podczas generowania jądra i nie mogą być później usuwane. Ich zadaniem jest odseparowanie reszty systemu od sprzętu. System wejścia/wyjścia systemu UNIX jest podzielony na dwie części, zgodnie z klasyfikacją urządzeń, tj. część obsługująca urządzenia blokowe i część obsługująca urządzenia znakowe. Celem części systemu, która obsługuje operacje wejścia/wyjścia urządzeń blokowych, czyli przede wszystkim dysków, jest minimalizacja liczby przesyłań do i z dysku. W tym celu stosuje się pamięć notatnikową buforów, która jest umieszczana między systemem plików a modułami obsługi dysków. Przy wykonywaniu operacji odczytu z urządzenia w pierwszej kolejności przeszukiwana jest pamięć notatnikowa buforów. Jeżeli w buforze znaleziono odpowiedni blok danych, to nie ma potrzeby wykonywania czasochłonnej operacji wejścia/wyjścia. Jeżeli nie znaleziono, to wyszukuje się bufor z listy wolnych buforów, aktualizuje się numer urządzenia i numer bloku i wykonuje operację odczytu do pamięci notatnikowej. Jeżeli nie ma wolnych buforów to wyszukuje się bufor z danymi które najdłużej czekały na zapis. Dane z tego bufora zostają zapisane na urządzenie wyjściowe a zwolniony bufor może być wykorzystany przez operację odczytu. Informacja o tym, że blok danych znajduje się w buforze, zawarta jest w nagłówku bufora. Pamięć notatnikowa jest wykorzystywana zarówno przy wykonywaniu operacji zapisu, jak i odczytu. W celu utrzymania spójności systemu plików w przypadku awarii zawartości pamięci notatnikowej, jest zapisywana na dysk co 30 sekund.
Mechanizm zarządzania pamięcią operacyjną różni się znacznie w zależności od wersji systemu. Jest to ściśle związane z ograniczeniami sprzętowymi. W wersjach systemu wcześniejszych niż UNIX 3 BSD oraz prostych wersjach systemu, wykorzystywanych na sprzęcie klasy PC technika wymiany obszarów pamięci pomiędzy pamięcią operacyjną, a dyskową jest stosowana w ograniczonym zakresie. To znaczy, że jeżeli w systemie znajduje się zbyt wiele procesów i brakuje wolnego obszaru pamięci operacyjnej, to niektóre z tych procesów są usuwane (często używa się pojęcia wymiatane  - and. swapping) na dysk, aż zwolni się wystarczająco duży obszar pamięci operacyjnej. Alokacja pamięci odbywa się w tego typu systemach według algorytmu FF (ang. First Fit). Jeśli w danej chwili nie ma odpowiednio dużo, spójnego obszaru pamięci proces ulega zawieszeniu. Decyzję o tym, który proces ma być wprowadzony do pamięci operacyjnej lub z niej usunięty, podejmuje proces zawiadowcy (scheduler) czyli proces 0 (w niektórych systemach zwany również pod nazwą swapper process) Proces zawiadowcy jest budzony okresowo (zazwyczaj co kilka sekund) i sprawdza które procesy powinny być usunięte z pamięci, a które do niej wprowadzone. W pierwszej kolejności są usuwane procesy najdłużej przebywające w pamięci lub procesy duże i podobnie wprowadzane są procesy, które były poza systemem najdłużej lub są małe. Aby uniknąć problemu migotania, nie pozwala się na usunięcie procesów, które nie przebywały w systemie przez określony czas. Taki schemat zarządzania pamięcią operacyjną wykorzystuje wiele wersji systemu UNIX: wszystkie systemy USG (UNIX Support Group) z wcześniejszymi wersjami UNIX System V włącznie. Technika stronicowania została wprowadzona po raz pierwszy w systemie UNIX 3 BSD. Obecnie wykorzystuje się ją w systemach UNIX BSD i najnowszych wersjach UNIX System V. Są to systemy z pamięcią wirtualną, ze stronicowaniem na żądanie. Technika ta jest realizowana w sposób bezpośredni, to znaczy, że jeżeli proces potrzebuje strony, której w danej chwili nie ma w pamięci operacyjnej, to do jądra systemu jest wysyłane przerwanie - "błąd strony", alokowana odpowiednia ramka w pamięci operacyjnej i właściwa strona czytana z dysku. Obraz pamięci operacyjnej w systemie UNIX 4 BSD - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 124.]

W dolnym obszarze pamięci znajduje się jądro systemu a nad nim mapa pamięci (core map). Pozostała część pamięci operacyjnej jest podzielona na ramki stron, które mogą zawierać: tekst programu, segment danych, stos, strukturę użytkownika i tablicę odwzorowania stron lub mogą być po prostu nie wykorzystane. Mapa pamięci stanowi zbiór informacji o zawartości ramek stron. Pozycja numer 0 mapy pamięci opisuje ramkę stron nr. 0, pozycja numer 1 - ramkę nr. 1 itd. Ramki stron mają najczęściej rozmiar 1KB, natomiast poszczególne pozycje w mapie pamięci opisujące ramki są 16-bitowe. Z reguły mapa pamięci nie przekracza 2% całkowitego obszaru pamięci operacyjnej. Usuwanie stron z pamięci operacyjnej przebiega w dwóch etapach. Najpierw strona jest oznaczana w tablicy odwzorowania stron procesu jako nieważna i na razie w stosunku do niej nie są podejmowane żadne akcje. Jeżeli na tym etapie zostanie wygenerowany sygnał przerwania "błąd strony", to strona, której przerwanie to dotyczy, może być wtedy oznaczona jako ważna i można ją wykorzystać bez konieczności wykonywania operacji wejścia/wyjścia to jest sprowadzania ją z pamięci zewnętrznej. Najczęściej wykorzystuje się algorytm wymiany stron LRU. Algorytm ten opiera się na założeniu, że strona z pamięci operacyjnej, która najdłużej nie była wykorzystana, nie będzie prawdopodobnie wykorzystana w najbliższej przyszłości. Mapa pamięci operacyjnej (z wyłączeniem jądra) jest cyklicznie i liniowo przeglądana przez program o nazwie clock hand (w BSD - two handed clock, w System V - one handed clock). Jeżeli ramka jest wolna, program bada następną i jeżeli jest w niej wpisana jakaś strona, to następuje sprawdzenie odpowiedniego zapisu w tablicy odwzorowania stron. Jeżeli strona występuje jako nieważna, to jest usuwana, a ramka dodawana do listy ramek wolnych. Natomiast jeśli strona jest oznaczona jako ważna i aktualnie nie jest wykorzystywana przez operacje wejścia/wyjścia, to jest status ulega zmianie na nieważny i stronę pozostawia się na razie w spokoju. W systemie kontroli podlega również liczba stron ze statusem ważna, tak aby nie obniżyła się ona zbytnio, co mogło by spowodować nagły wzrost żądań sprowadzenia stron z pamięci dyskowej. Proces clock hand jest zaimplementowany jako część procesu 2 - pagedaemon (swapper jest procesem 0, init procesem 1). Proces ten większość czasu "śpi", lecz w tym czasie trwa sprawdzanie (kilka razy na sekundę), czy konieczna jest w systemie interwencja tego procesu. Jeżeli tak proces 2 zostaje obudzony, na przykład gdy liczba ramek w p.o. spadnie poniżej pewnej wartości progowej (lotsfree) - zazwyczaj 1/4 pamięci. Proces clock hand uwzględnia podczas pracy zarówno to, ile ramek brakuje do osiągnięcia wartości progowej, jak i wskazówek zawiadowcy. Jeżeli proces zawiadowcy zadecyduje że system jest przeładowany, to pewne procesy są z systemu usuwane, aż przeładowanie zniknie. Brane są przy tym pod uwagę pewne dodatkowe parametry, tj. minfree najniższy limit wolnej pamięci oraz desfree średni rozmiar dostępnej pamięci w ostatnim okresie. Innymi słowy procesy są usuwane, jeśli w systemie wystąpił brak pamięci. Omówiony mechanizm zarządzania pamięcią operacyjną jest mechanizmem systemowym, a więc ingerencje użytkowników są w nim niemożliwe. System UNIX dostarcza jednak pewne dodatkowe możliwości ingerowania w organizację pamięci wykorzystywanej przez programy aplikacyjne. Służy do tego zestaw funkcji systemowych, pozwalających na zdefiniowanie i manipulowanie tzw. pamięcią współdzieloną. Pamięć współdzielona (shared memory) służy do przekazywania danych między procesami. Obszar współdzielony musi zostać utworzony z wykorzystaniem funkcji systemowej shmget z argumentami klucz, rozmiar i tryb dostępu (inaczej - flagi dostępu - and. shmflag). Funkcja ta zwraca identyfikator obszaru. Każdy z procesów, który chce wymieniać dane poprzez ten obszar musi dołączyć go funkcją shmat, podając jako argumenty identyfikator uzyskany z shmget, adres pod którym proces chce widzieć obszar (gdy adres jest równy zero system przyłącza obszar pod pierwszym wolnym adresem) oraz flagi dostępu. Funkcja shmat zawiera adres, pod którym obszar współdzielony jest widoczny w danym procesie. Po zakończeniu korzystania z obszaru proces odłącza go wykonując funkcje shmdt, przekazując jako argument adres obszaru.


UNIX, Linux powłoka (shell) - kurs

W tym post-cie, opiszę teoretycznie powłokę UNIX-a.
Jest to trzecia część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach opiszę: jądro UNIX-a oraz funkcje systemowe związane z procesami na bazie UNIX-a.
W części pierwszej opisałem: wstęp do UNIX-a.
W części drugiej opisałem: system plików UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



Po zarejestrowaniu się użytkownik ma dostęp do sytemu poprzez interpretator poleceń nazwany powłoką (shell). Może uruchomić własne programy, aplikacje bądź ogólnie dostępne programy systemowe.

Użytkownik, powłoka a jądro systemu:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 73.]

Powłoka w systemie UNIX zapewnia komunikację między użytkownikami a systemem. Jest ona w stosunku do jądra zwykłym programem aplikacyjnym, w związku z tym nie rezyduje na stałe w pamięci operacyjnej, a często bywa dopasowywana do potrzeb użytkowników. W systemie są zazwyczaj dostępne dwie wersje powłoki Bourne Shell oraz U.C. Berkeley C Shell. Powłoka jest inicjowana automatycznie po zarejestrowaniu się użytkownika w systemie. Skoro jest to zwykły program aplikacyjny, to jego nowy egzemplarz może uruchomić w dowolnej chwili poleceniem sh. Innymi słowy, polecenie sh uruchamia nowy proces interpretatora czytając dane z klawiatury. Wszystkie następne polecenia są kierowane do sytemu operacyjnego przez powłokę. Powłoka przejmuje polecenia od użytkownika, dekoduje je i przekazuje do jądra w celu wykonania.

Pracę powłoki można przedstawić algorytmicznie jako ciąg następujących czynności:
 - wysłanie znaku gotowości ($) na terminal,
 - przyjęcie polecenia od użytkownika,
 - zdekodowanie polecenia i odszukanie w katalogach odpowiedniego mu programu,
 - przekazanie polecenia do jądra w celu utworzenia odpowiedniego procesu (lub procesów) realizujące polecenie i oczekujące na jego zakończenie,
 - przyjęcie odpowiedzi od jądra i przekazanie tych wyników użytkownikowi,
 - powrót do punktu pierwszego.

Czynności te wykonuje się w pętli aż do napotkania przez powłokę znaku ctrl-d wprowadzonego z klawiatury. Powłoka zleca wówczas jądru zamknięcie sesji użytkownika.

Ponieważ powłoka traktuje nazwę polecenia jako nazwę programu, to jest ona wyszukiwana w katalogach, na ogół w następującej kolejności:
1) katalog bieżący użytkownika
2) katalog /bin
3) katalog /usr/bin.

Nazwa polecenia musi pojawić się w jednym z katalogów jako nazwa pliku zwykłego, w stosunku do którego użytkownik ma prawo wykonania. Dzięki temu można uniknąć podawania za każdym razem pełnej nazwy ścieżkowej pliku zapisanego w jednym z katalogów przeszukiwanych automatycznie. Powłoka systemu UNIX pozwala na szereg udogodnień w pracy użytkownika z systemem. Przeadresowywanie wejścia/wyjścia polega na zamianie standartowych urządzeń wprowadzania i wyprowadzania informacji na inne wygodne dla użytkownika. Każdemu procesowi w chwili uruchomienia przypisuje się automatyczne standardowy strumień wejściowy i wyjściowy. Normalnie są one dołączone odpowiednio do klawiatury i ekranu terminalu. Większość programów wypisujących informację wypisuje je do standardowego strumienia wejściowego. Użytkownik nie musi więc podawać, gdzie należy kierować wyniki.  Kierunki wprowadzania i wyprowadzania są oznaczone odpowiednio znakami "<" i ">". Przetwarzanie potokowe - powłoka umożliwia tworzenie łączy komunikacji między procesami i tworzy tzw. potok (pipeline). Łącza kierują wyniki jednego programu do wejścia drugiego. Dla jednego programu łącze stanowi plik wyjściowy, dla drugiego - plik wejściowy. Łącze przedstawia się jako "|". Tak więc przetwarzanie potokowe to bezpośrednie przekazanie danych z jednego programu usługowego do drugiego. Innymi słowy, łącze tworzy się wiążąc bezpośrednio standardowy strumień wyjściowy procesu ze standardowym strumieniem wejściowym następnego, bez żadnego fizycznego pliku pośredniego (np. who | lp - to żądanie wykonania potoku składa się z dwóch procesów, po zdefiniowaniu potoku jądro natychmiast uruchamia oba procesy. W tak skonstruowanym potoku wyniki programu who są przekazywane do programu lp od razu po ich pojawieniu się, bez czekania na zakończenie pracy pierwszego programu.). Wieloprogramowość - system operacyjny UNIX jest systemem wieloprogramowym, to znaczy takim, który pozwala użytkownikom na współbieżne wykonywanie w danej chwili wielu programów (właściwie należy mówić o współbieżnej pracy procesów wykonujących programy, bowiem w systemie UNIX odróżnia się proces, czyli obiekt dynamiczny tworzony przez system, od wykonywanego przez proces programu, czyli obiektu statycznego, zapisanego jako plik).


UNIX, Linux system plików - kurs

W tym post-cie, opiszę teoretycznie system plików UNIX-a.
Jest to druga część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach opiszę: powłokę UNIX-a, jądro UNIX-a oraz funkcje systemowe związane z procesami na bazie UNIX-a.
W części pierwszej opisałem: wstęp do UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



W systemie UNIX jeden logiczny system plików widziany przez użytkownika może składać się z kilku fizycznych systemów plików znajdujących się na kilku urządzeniach fizycznych. Z kolei każde urządzenie fizyczne może być podzielone na urządzenie logiczne, a każde z nich może zdefiniować własny system plików. Jednakże w systemie musi istnieć jeden wyróżniony system plików zawierający katalog pierwotny - korzeń całego systemu. System ten znajduje się na dyskach niewymiennych i do niego są dołończone inne systemy plików przechowywane na nośnikach wymiennych.

Logiczny system plików:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 28.]

Dany logiczny system plików jest ciągiem bloków ponumerowanych kolejno 0..n, przy czym kolejne bloki stanowią:
 - blok 0 (boot block) - jest zawsze zarezerwowany dla programu ładującego i sterującego systemem,
 - blok nadrzędny (super block),
 - lista tzw. i-węzłów plików (i-node list),
 - bloki danych,
 - obszar do wymiatania programów (swapping space).

W bloku nadrzędnym zawarte są następujące informacje o systemie plików:
 - rozmiar w blokach,
 - nazwa urządzenia logicznego,
 - nazwa systemu plików,
 - rozmiar listy węzłów plików,
 - wskaźnik na pierwszy element listy wolnych bloków,
 - wskaźnik na pierwszy element listy wolnych węzłów plików,
 - data ostatniej modyfikacji,
 - data ostatniego dostępu,
 - rozmiar bloku.

System operacyjny UNIX zaprojektowano tak, aby przede wszystkim przetwarzał pliki, a więc każdy zbiór informacji traktuje on jako plik, przy czym nie ważne, jak i na czym ta informacja jest zapisana. Informacja zewnętrzna o plikach (tj. nazwa, wielkość, właściciel, czas powstania i prawa dostępu) jest zapisana w katalogu który sam jest plikiem w ogólności, katalog jest plikiem zawierającym listę nazw plików wraz z odpowiednimi numerami węzłów informacyjnych (i-node). Węzły informacyjne pliku będziemy nazywać i-węzłami pliku.

Budowa katalogu w systemie UNIX:
 
[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 29.]

Informacja wewnętrzna pliku (dane, program, tekst dokumentu, itp.) stanowi zawartość pliku. Interesujące jest, że plik w systemie UNIX nie ma struktury wewnętrznej, w szczególności nie dzieli się na mniejsze jednostki. Formalnie jest on ciągiem znaków zakończonych EOF. Jedynymi znakami zawartymi w pliku są znaki umieszczone tam przez użytkownika.  Ponieważ nie ma wstępnej alokacji miejsca na dysku, plik może mieć dowolną długość. System plików jest zorganizowany hierarchicznie, tzn. każdy plik wyższego poziomu może zawierać odsyłacze do plików niższego poziomu, a każdy plik niższego poziomu musi znajdować się w wykazie co najmniej jednego pliku wyższego poziomu.

W praktyce katalogiem nadrzędnym wobec wszystkich innych jest tzw. katalog pierwotny (root-korzeń), zawierający wykaz katalogów kilku podstawowych rodzajów:
 - bin (programy  usługowe w wersji gotowej do wykonania - binarnej),
 - dev (pliki specjalne odpowiadające urządzenia zewnętrznym,
 - lib ( programy biblioteczne, związane z językiem wysokiego poziomu, wywołaniami systemowymi, obsługą I/O),
 - usr (wykaz wszystkich katalogów niższego poziomu, w których przechowują w swoje pliki użytkownicy, zazwyczaj sporządzony według nazw użytkowników),
 - tmp (pliki tymczasowe),
 - etc (dane i programy podlegające ścisłej ochronie),
 - inne katalogi (np. lost+found - zawiera pliki utracone, tzn. takie, które straciły właściwe powiązanie z systemem plików).

Oprócz wymienionych katalogów w katalogu pierwotnym znajduje się jeden plik o nazwie unix - nie będący katalogiem. Jest to jądro systemu operacyjnego. Pliki specjalne reprezentujące urządzenia zgrupowane są w katalogu /dev. Wpisane są w nim pliki pseudourządzeń i urządzeń rzeczywistych.

Do pseudourządzeń należą między innymi:
 - /dev/console (konsola systemowa, na którą są wyprowadzane komunikaty systemowe),
 - /dev/kmem (odwzorowanie wirtualnej pamięci operacyjnej),
 - /dev/tty (wirtualny terminal, z którego został zainicjowany proces).

Urządzenia rzeczywiste to:
 - /dev/fdn (stacja dysków elastycznych),
 - /dev/hdn (stacja dysków twardych),
 - /dev/lp (drukarka).

Przy rejestrowaniu nazwy użytkownika w systemie zostaje z nią związany katalog osobisty danego użytkownika. Katalog ten staje się katalogiem bieżącym w chwili rozpoczęcia przez użytkownika sesji przy terminalu. Jak wynika z podstawowych powyżej rozważań, z punktu widzenia użytkownika plik jest identyfikowany przez nazwę sieciową. Na jej podstawie system musi zlokalizować bloki dyskowe pliku, czyli miejsce, w którym plik jest przechowywany na dysku. Podstawą lokalizacji bloków dyskowych pliku są węzły informacyjne pliku. Zawiera ona zestaw informacji opisujących plik (tzn. atrybuty pliku) oraz opis organizacji fizycznej pliku (wskaźniki do dyskowych bloków danych). Atrybuty pliku zawarte w jego węźle informacyjnym przedstawia rysunek.

Struktura węzła informacyjnego pliku:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 33.]

Wszystkie adresy dyskowe plików o rozmiarze nie przekraczającym 10 bloków są przechowywane bezpośrednio węźle informacyjnym pliku. Jeśli plik jest większy niż 10 bloków, potrzebny jest dodatkowy blok zawierający adresy pozostałych bloków pliku, natomiast w węźle informacyjnym przechowywany jest adres tego bloku, tzn. wskaźnik na wskaźnik pośredni. W zależności od rozmiaru bloku dyskowego i długości adresu pojedynczy blok pośredni może zawierać od 128 do 256 adresów. Pliki specjalne (np. pliki urządzeń) nie mają bloków danych alokowanych na dysku. Jądro systemu odnotowuje pliki tego typu na podstawie informacji z i-węzłów, a następnie wywołuje odpowiednie moduły obsługi urządzeń w celu wykonania operacji wejścia/wyjścia dla tych plików. Aby zapisać plik na dysku, system plików musi dysponować informacją o rozmieszczeniu bloków wolnych tego dysku. Informacja  o blokach wolnych w systemie UNIX jest najczęściej utrzymywana w postaci listy łańcuchowej przechowywanej w bloku nadrzędnym. W systemie UNIX ten sam plik może występować pod dwiema lub więcej nazwami, a co więcej - z możliwością ich występowania w różnych katalogach. Typowym wykorzystaniem jest tutaj pozwolenie np. kilku członkom jednego zespołu programistycznego na współdzielenie tego samego pliku, przy czym może on występować w różnych katalogach pod różnymi nazwami (nie są to prywatne kopie). Zmiany w pliku dokonywane przez jednego użytkownika są widoczne dla innych. Taką możliwość uzyskuje się przez mechanizm tzw. łączników. Łączniki do pliku tworzy się po to, aby uniknąć niepotrzebnego kopiowania i przechowywania wielokrotnych kopii tego samego pliku. W przypadku utworzenia łącznika specjalnym poleceniem plik otrzymuje drugą nazwę (traktowaną jako synonim), lecz jego właścicielem pozostaje poprzedni użytkownik.
Po znalezieniu pliku związane z nim informację, takie jak rozmiar, właściciel, prawa dostępu i umiejscowienie bloków danych są z reguły kopiowane do tablicy nazwanej tablicą otwartych plików, znajdującej się w pamięci operacyjnej i zawierającej informację o wszystkich bieżąco otwartych plikach. Pierwsze odwołanie do pliku (zazwyczaj operacja jego otwarcia - open) powoduje przeszukanie katalogu i przekopiowanie wpisu katalogowego dotyczącego danego pliku do tablicy otwartych plików. Do programu użytkownika zostaje przekazany indeks do tej tablicy, wszystkie dalsze odwołania są więc wykonywane za pomocą tego indeksu, a nie nazwy symbolicznej. W systemach uniksowych nazywa się go deskryptorem pliku. Tak więc dopóki nie nastąpi zamknięci pliku, dopóty wszystkie operacje plikowe są wykonywane z użyciem tablicy otwartych plików. Po zamknięciu pliku przez wszystkich korzystających z niego użytkowników uaktualniane informacje o nim są z powrotem kopiowane do dyskowej struktury katalogowej. W niektórych systemach schemat ten komplikuje się jeszcze bardziej wskutek zastosowania w p.o. tablic wielopoziomowych. Podstawowym elementem wykorzystywanym przez system w zarządzaniu plikami są węzły informacyjne plików. Prócz nich system wykorzystuje również tablice otwartych plików bieżącego procesu, tablicę struktury pliku oraz wewnętrzny i-węzeł (węzeł informacyjny przechowywany w pamięci operacyjnej). Wywołania systemowe, które dotyczą otwartych plików, wskazują pliki poprzez tzw. deskryptor pliku. Deskryptor pliku jest używany przez jądro do indeksowania tablicy otwartych plików bieżącego procesu. Każdy zapis w tej tablicy zawiera wskaźnik do tablicy struktury pliku i dalej do wewnętrznego i-węzła. Tablica struktury plików została wprowadzona ze względu na to, że kilka procesów działających na danym pliku "widzi" go inaczej; mówimy, że proces dysponuje określonym przesunięciem (offset) w obrębie pliku.

Bloki kontrolne systemu plików - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 35.]



UNIX, Linux - kurs

W tym post-cie, opiszę teoretycznie system UNIX.
Jest to pierwsza część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach opiszę: system plików UNIX-a, powłokę UNIX-a, jądro UNIX-a oraz funkcje systemowe związane z procesami na bazie UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



Twórcami systemu są Ken Thompson i Dennis Ritchie pracujący w Bell Laboratories.

Trzy główne wersje systemu:
 - UNIX System V Release 4,
 - 4.4 BSD (University of California w Berkeley),
 - Solaris (SunOs).

Charakterystyczne cechy systemu UNIX:
 - wielodostępność,
 - wieloprocesowość (wielozadaniowość),
 - hierarchiczny system plików, z jednolitym potraktowaniem plików zwykłych, katalogów i plików opisujących urządzenia zewnętrzne,
 - duża liczba programów narzędziowych,
 - duża liczba programów usługowych,
 - przenośność oprogramowania systemowego dzięki zapisowi w języku C,
 - wykonywanie operacji wejścia/wyjścia niezależnie od typu urządzeń zewnętrznych,
 - warstwowa budowa systemu.

Każdy system operacyjny ma wyodrębnioną część, która realizuje jego najbardziej podstawowe funkcję. Część tę nazywa się jądrem systemu (warstwą wewnętrzną). Zwykle warstwa zewnętrzna obejmuje procesy użytkowników. Każdej akcji wykonanej poza jądrem odpowiada pewien proces. Wśród procesów warstwy zewnętrznej specjalną rolę odgrywa tzw. powłoka (shell), Jest to proces odpowiadający za konwersację z użytkownikiem, tzn. interpretujący polecenia wprowadzane z klawiatury terminalu.

Przykładowa struktura systemu operacyjnego UNIX:

[Rysunek jest w całości mojego autorstwa, bazuje częściowo na rysunku z książki, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 10.]

Najważniejsze funkcje jądra:
 - zarządzanie procesami (szeregowanie, synchronizacja),
 - zarządzanie pamięcią,
 - obsługa urządzeń I/O,
 - obsługa systemu plików,
 - obsługa przerwań,
 - przydział procesora,
 - rozdzielenie zasobów.

Najważniejsze usługi świadczone przez jądro:
 - zarządzanie procesami,
 - zarządzanie pamięcią,
 - zarządzanie plikami,
 - obsługa urządzeń I/O.

Proces składa się z:
 - wykonywanego programu,
 - danych,
 - stosu i wskaźnika stosu,
 - licznika rozkazów, i innych rejestrów oraz innych informacji niezbędnych do wykonywania programu.

Jeżeli system pracuje w trybie podziału czasu, to proces może być czasowo zawieszony, a później restartowany w tym samym stanie, jak przed zawieszeniem. W większości systemów operacyjnych wszystkie informację o każdym procesie są przechowywane w tablicy procesów. Tak więc proces składa się z przestrzeni adresowej (nazywanej często obrazem pamięci) oraz z zapisów w tablicy procesów (są to przede wszystkim zawartości rejestrów procesora). Procesem, który czyta zlecenia z terminalu, jest powłoka. Z procesami związane są sygnały (signal). Sygnały są programowym odpowiednikiem przerwań na poziomie sprzętu. Hierarchia procesów i plików jest zorganizowana w postaci drzewa (hierarchia procesów nie jest głęboka (do trzech poziomów) i zazwyczaj jest krótkotrwała). System operacyjny UNIX nie pozwala, aby ścieżka była poprzedzona nazwą lub numerem napędu dyskowego. Tak, więc aby móc wykorzystać w systemie katalog znajdujący się na dyskietce, należy najpierw przyłączyć go do katalogu korzenia, który zazwyczaj znajduje się na dysku twardym. Pliki i katalogi w systemie UNIX są chronione 9-bitowym katalogiem ochronnym. Jeśli dostęp do pliku jest dozwolony, system wysyła do procesu deskryptor pliku, wykorzystywany w kolejnych operacjach. W systemie UNIX wyróżniono tak zwane pliki specjalne. Pozwalają one na widzenie urządzeń I/O tak, jakby to były zwykłe pliki. W ten sposób operacje zapisu i odczytu z tych urządzeń mogą być wykonywane w wykorzystaniem tych samych wywołań systemowych, które dotyczą zapisu i odczytu plików.


Skrypt SQL w ADOQuery z wieloma instrukcjami - C++ Builder i Delphi

W tym post-cie, zademonstruję funkcję za pomocą, której można wykonywać skrypty SQL składające się z dowolnej liczby instrukcji.

Funkcję tę można używać w Delphi od wersji 7 do najnowszej (w chwili pisania post-u) czyli Delphi XE 2, oraz w C++ Builder od wersji 6.0 do najnowszej (w chwili pisania post-u) czyli C++ Builder XE2. W zasadzie we wcześniejszych wersjach też, ale testowałem tylko od Delphi 7.0 i od C++ Builder 6.0.

Domyślnie komponenty ADOQuery, ADOCommand nie umożliwiają wykonywania wielu instrukcji SQL rozdzielonych średnikami, można wykonywać tylko jedną instrukcję SQL. Moja funkcja to umożliwia, jest napisana w Delphi 7 i wstawiona do biblioteki DLL, aby w innych językach programowania było można jej też używać.

Po omówieniu funkcji i biblioteki DLL, zademonstruję jak ją używać w programie napisanym w Delphi 7.0 i programie napisanym w C++ Builder 2007 we współpracy z systemem baz danych SQL Server 2008R2 Express. Natomiast w kolejnym post-cie (tego tematu), zademonstruję tę samą bibliotekę DLL, ale kompatybilną ze znakami UNICODE i systemami baz danych obsługującymi znaki UNICODE, wraz z przykładem użycia w Delphi 2010 i C++ Builder 2010.

Biblioteka DLL z funkcją, może być używana z wszystkimi dostępnymi systemami baz danych, które są obsługiwane przez komponent ADOQuery i dla który można skonstruować ConnectionString.

Więcej o konstruowaniu ConnectionString, można poczytać w linku poniżej:
Patrz tutaj (język ang.).


Do tego post-a załączam również kompletne pliki źródłowe biblioteki DLL, pliki źródłowe z przykładem użycia tej biblioteki DLL (z funkcją do wykonywania skryptów SQL) w Delphi 7.0 i C++ Builder 2007.

Ważne jest to, że aby używać tej funkcji zaszytej w bibliotece DLL, nie musicie nic o niej widzieć, poza znajomością jej nagłówka, co więcej wszystkie potrzebne komponenty, w tym TADOQuery i TADOConnection są wewnątrz niej tworzone dynamicznie.

Zaczynamy od kodu biblioteki DLL (wewnątrz funkcja do wykonywania skryptów SQL), następnie omówię jej najważniejsze aspekty, a na koniec przedstawię sposób jej używania w Delphi i C++ Builder.




Co do samej biblioteki DLL, tylko jedna uwaga pominąłem moduł ShareMem, który jest potrzebny gdy używamy biblioteki DLL w wielu językach programowania, a nagłówek funkcji ma w sobie parametry string.
Jak widzicie, ja nie użyłem tego modułu, a biblioteka DLL jest używana w wielu językach programowania.
Jak to możliwe? - po prostu w nagłówku funkcji użyłem zmiennych PChar, zamiast string-ów. Dzięki temu rozwiązałem bardzo poważny problem. Gdy ładujemy bibliotekę DLL dynamicznie i dynamicznie ją zwalniamy, czyli używamy jej w działającym programie w zależności od potrzeby, wtedy moduł ShareMem, nie może być dołączony do biblioteki DLL, ponieważ po zwolnieniu biblioteki DLL wyskakuje wyjątek (JEST TO OGÓLNIE PRZYJĘTY NIENAPRAWIONY BUG, przynajmniej ja tak myślę i tak wyczytałem w wielu źródłach). Zatem moje rozwiązanie z PChar i wieloma językami programowania jest jedyne możliwe (przynajmniej ja tak myślę).

Omówmy teraz samą funkcję, w zasadzie sam nagłówek funkcji oraz kod w ciele funkcji, który odpowiada za dynamiczne używanie komponentów ADO w bibliotekach DLL i wątkach. Resztę ciała funkcji zostawiam Wam do analizy.

Nagłówek:

function Wykonaj_Skrypt_SQL_W_ADOQuery_DELPHI_C(
connection_string_Delphi: PChar;
skryptSQL_Delphi: PChar;
pokazuj_instrukcje_SQL: Bool):Bool; stdcall;


Pierwszy parametr to wspomniany wcześniej ConnectionString,
drugi to skrypt SQL,
trzeci to parametr odpowiedzialny za decyzję, czy podczas wykonywania skryptu mają pojawiać się po kolei w ShowMessage wykonywane instrukcje.
Funkcja zwraca wartość true jeśli skrypt SQL wykonał się w całości, w zasadzie jeśli transakcja wykonała sie w całości, lub false jeśli skrypt SQL nie wykonał się w całości, transakcja zostanie cofnięta.

Ważne jest to, aby pamiętać, że nie wszystkie systemy baz danych odsługują transakcje lub obsługują transakcje częściowo.
Przykład: MySQL, nie obsługuje transakcji DDL, nie ma problemu z DML.
Czyli wykonując skrypt SQL za pomocą mojej funkcji z biblioteki DLL, gdy najpierw utworzymy tabelę, potem do niej wstawimy wierz i kolejny wierz, ale ten drugi wierz wstawimy z takim samym kluczem głównym, moja funkcja wykona ROLLBACK, cofnie transakcje, bo nie można wstawić dwa razy wiersza z tym samym kluczem głównym, ale utworzona tabela pozostanie, gdyż MySQL nie wspiera transakcji DDL, wiersz pierwszy zostanie cofnięty przez ROLLBACK, czyli de facto będziemy mieli pusta tabelę. Problem ten nie wystąpi np. w SQL Server - przy opisanym schemacie postępowania nie będziemy mieli nawet tabeli.

Gdy Wasz skrypt SQL obojętnie jakiego systemu baz danych dotyczy nie zawiera instrukcji odpowiedzialnych za wykonywanie transakcji moja funkcja już o to zadba.
Gdy Wasz skrypt SQL obojętnie jakiego systemu baz danych dotyczy zawiera instrukcje odpowiedzialne za wykonywanie transakcji zostaną one uwzględnione i cały skrypt SQL zostanie opatrzony jedną transakcją nadrzędną.

Poniższy kod jest wymagany, gdy używamy komponentów ADO wewnątrz bibliotek DLL lub wewnątrz wątków (Wątki nie są przedmiotem tego posta).

//KOD wymagany, dla używania komponentów ADO, w bibliotekach DLL i w wątkach.
try
OleInitialize(nil);
komponentADOQuery^ := TADOQuery.Create(nil);
komponentADOQuery^.Connection := connection^;
komponentADOQuery^.Connection.LoginPrompt := False; //opcja
komponentADOQuery^.Connection.ConnectionString:= connection_string^;
//KONIEC KODU WYMAGANEGO

...

//KOD wymagany, dla używania komponentów ADO, w bibliotekach DLL i w wątkach.
komponentADOQuery^.Connection.Close;
//KONIEC KODU WYMAGANEGO

...

//KOD wymagany, dla używania komponentów ADO, w bibliotekach DLL i w wątkach.
finally
try
connection^.Free;
komponentADOQuery^.Free;
except
;
end;
try
OleUninitialize;
except
;
end;
end;
//KONIEC KODU WYMAGANEGO


No i nadszedł czas na użycie opisanego powyżej kodu.

Przykład DELPHI 7.0:




Przykład C++ Builder 2007:




Podaję również przykład ConnectionString dla połączenia z SQL Server 2008R2 Express z instancją bazy danych SQLExpress i autoryzacją ustawioną na autoryzację Windows.
Ten ConnectionString korzysta z baz danych temodb, czyli wszystkie skrypty SQL wykonane przy pomocy mojego programiku, np. tworzące tabele zostaną automatycznie "unieważnione" po restarcie serwera SQL Server 2008R2 Express. Tabela tempdb jest czyszczona przy każdym uruchamianiu serwera baz danych SQL Server.

Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=tempdb;Data Source=.\SQLExpress


Pliki do pobrania:
1. Źródła biblioteki DLL
-pobierz
2. Źródła przykładowego programu w Delphi 7.0 korzystającego z biblioteki DLL
-pobierz
3. Źródła przykładowego programu w C++ Builder 2007 korzystającego z biblioteki DLL
-pobierz
4. Tylko plik wykonywalny przykładowego programu w Delphi 7.0 korzystającego z biblioteki DLL
-pobierz
5. Tylko plik wykonywalny przykładowego programu w C++ Builder 2007 korzystającego z biblioteki DLL
-pobierz
6. Źródła przykładowego programu w Delphi 2007 korzystającego z biblioteki DLL i źródła biblioteki DLL w Delphi 2007
-pobierz



Pomagali: Arkadiusz Dymek, Edek Pienkowski, Zenek Bóbr, Marek Borowski, Piotr Sietnik, Michoo - więcej -> Skrypt SQL w ADOQuery z wieloma instrukcjami


Kolorowanie składni kodu SyntaxHighlighter 2 i 3 - blogger, HTML i PHP

W tym post-cie przedstawię narzędzie do kolorowania (podświetlania) składni (ang. syntax highlighting) - o nazwie SyntaxHighlighter.

Techniki syntax highlighting używa się najczęściej do wyróżniania elementów składniowych kodu źródłowego programu (np. słów kluczowych, komentarzy) w edytorze tekstu za pomocą koloru oraz atrybutów. Funkcja ta dostępna jest obecnie w większości programistycznych edytorach tekstu i we wszystkich narzędziach programistycznych.

Nic nie stoi na przeszkodzie, abyś sam cieszył się z funkcji: "Kolorowania składni", które oferują narzędzia programistyczne na Swoim blogu (w tym na blogger), czy też w Swoim projekcie programistycznym (np. w kodzie xhtml [html], wyprodukowanym z PHP).

Zademonstruję i opiszę użycie narzędzia SyntaxHighlighter w najnowszej wersji 3, które umożliwia technikę syntax highlighting. Demonstracja i opis będzie obejmował blogi (z głównym naciskiem na blogger) oraz strony internetowe (serwisy internetowe) w PHP, choć nie tylko.


ZACZYNAMY, powodzenia!:

Legenda:
a - odnosi się do bloga;
b - odnosi się do PHP;

Pierwszy krok

1a.: Umieść poniższy kod w szablonie Twojego bloga;
1b.: Umieść poniższy kod w Twoim projekcie programistycznym w pliku PHP;
(Uwaga - dotyczy tylko opisu dla PHP: Możesz też pobrać wszystkie wymagane skrypty i zamiast internetowej lokalizacji skryptów [https://alexgorbatchev.com/pub/sh/current/...] - wprowadź Swoją lokalizację skryptów).
Często programiści w tym Ja, gdy tworzą projekty programistyczne pobierają wszystkie skrypty na Swój komputer (lokalnie), aby umieścić je w Swoim projekcie programistycznym, a następnie w projekcie na serwerze produkcyjnym do komercyjnego użytku.
Dlaczego? - a no dlatego, bo np. za 5 lat projekt z którego pobraliśmy skrypty może już nie istnieć lub np. serwer ze skryptami może chwilowo nie odpowiadać, mogą być prace konserwacyjne, a jak masz wszystkie skrypty u Siebie, to Ci nic nie grozi, Twój projekt programistyczny zawsze będzie funkcjonował.
Wady - w zasadzie tylko jedna, jak stworzysz projekt oddany do użytku komercyjnego z pobranymi skryptami, a w między czasie wyjdzie nowa wersja skryptów, komercyjna strona internetowa (komercyjny serwis internetowy) będzie korzystał ze starych wersji skryptów.
<link href='https://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='https://alexgorbatchev.com/pub/sh/current/styles/shThemeEmacs.css' rel='stylesheet' type='text/css'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushAS3.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushColdFusion.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushErlang.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushJavaFX.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushPowerShell.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushScala.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
<script src='https://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.strings.viewSource = "Podgląd źródła";
SyntaxHighlighter.config.strings.print = "Drukuj";
SyntaxHighlighter.config.strings.copyToClipboard = "Kopiuj do schowka";
SyntaxHighlighter.defaults['auto-links'] = false;
SyntaxHighlighter.all();
</script>

Zaczerpnięty powyższy kod bazuje na źródle Twórcy narzędzia.
Akapit - Basic Steps
Patrz tutaj (język ang.).
W powyższym kodzie są umieszczone skrypty wszystkich dostępnych w chwili pisania postu języków programowania wspieranych przez SyntaxHighlighter.
Ich lista jest dostępna na stronie Twórcy narzędzia.
Patrz tutaj (język ang.).

Skrypty z językami programistycznmi dołącza się dlatego, aby narzędzie SyntaxHighlighter, potrafiło je rozpoznać i właściwie "Pokolorować".

W związku z faktem, że blog jest dla wszystkich programistów Microsoft, Embarcadero (Borland) i OpenSource użyłem wszystkich dostępnych w danej chwili.

Następny krok (Krok II):

2a2b.: Teraz już możesz na Swoim blogu lub w Swoim projekcie programistycznym umieszczać "Kolorowanie składni";

Są dwie metody - każda ma swoje zalety i wady (patrz poniżej - Krok IV):

Pierwsza - I: <pre> method

Zaczynamy od przykładu:

Użycie (korzystamy z kolorowania dla JavaScript):

<pre class="brush: js">
/**
  * SyntaxHighlighter
  */
  function foo()
  {
    if (counter <= 10)
      return;
    // it works!
  }
</pre>

Wynik użycia:
/**
  * SyntaxHighlighter
  */
  function foo()
  {
    if (counter <= 10)
      return;
    // it works!
  }

Gdy kod programistyczny znajduje się pomiędzy: <pre> </pre>, czyli jest tekstem preformatowanym (więcej czytaj tutaj), wtedy nie może zawierać np. znaków: < i > muszą one zostać zamienione odpowiednio na tzw. encje: &lt; i &gt;
Konsekwencją tego jest fakt, że aby "Pokolorować", np. kod xhtml (html) - znacznika "a", należy zamienić <a href> na &lt;a href&gt.

W powyższym przykładzie jest podobny przypadek, instrukcja JS:
counter <= 10
- w pliku xhtml (html) w części dotyczacej JavaScript wyprodukowanym z PHP ma postać:
counter &lt;= 10

Jeśli narzędzie programistyczne nie zamienia kodu na encje, a chcemy użyć metody: <pre> method, musimy to zrobić ręcznie.
Można posłużyć się narzędziem do zamiany kodu na kod z encjami:
Polskie narzędzie online do zamiany kodu xhtml (html) - "tekstu" na kod xhtml (html) - "tekst" z encjami

Zaczerpnięty powyższy opis metody I - bazuje na źródle strony Twórcy narzędzia.
Akapit - <pre> method
Patrz tutaj (język ang.).

Druga - II: <script /> method

Zaczynamy od przykładu:

Użycie (korzystamy z kolorowania dla JavaScript):

<script type="syntaxhighlighter" class="brush: js"><![CDATA[
/**
  * SyntaxHighlighter
  */
  function foo()
  {
    if (counter <= 10)
      return;
    //it works!
  }
]]></script>

Wynik użycia:

W przypadku tej metody nie ma co się rozpisywać wystarczy na początku każdego kolorowanego kodu wstawić:
<script type="syntaxhighlighter" class="brush: js"><![CDATA[
a na końcu, gdy już nie chcemy kolorować wstawić:
]]></script>


Zaczerpnięty powyższy opis metody II - bazuje na źródle strony Twórcy narzędzia.
Akapit - <script /> method
Patrz tutaj (język ang.).

Krok III (konfiguracja):

Konfiguracja jest opisana na stronie Twórcy narzędzia.
Patrz tutaj (język ang.).
oraz
Patrz tutaj (język ang.).

Ja na swoim blogu użyłem następującej konfiguracji i się z Wami ją podzielę.

Na bazie pierwszego linku dokonałem konfiguracji:
Pierwsza linia kodu jest ważna dla blogów - musi być ustawiona na true, gdy umieszczamy narzędzie SyntaxHighlighter na blogger. Gdy korzystamy z SyntaxHighlighter, we własnych projektach programistycznych ustawaimy na false.
Druga, trzecia i czwarta linia zmienia domyślne angielskie nazwy na ich odpowiedniki polskie.
Druga linia dla opisu: pokaż źródło.
Trzecia linia dla opisu: drukowanie.
Czwarta dla opisu: kopiowanie dla schowka.
W starszych wersjach SyntaxHighlighter, czyli w wersji 2.1 i starszych, każde "Kolorowanie składni" miało własne menu z 4 ikonami: "viewSource", "print", "copytoclipboard" oraz "?".
W wersji 3 nie wiadomo dlaczego to menu się nie pojawia, ale na wszelki wypadek postanowiłem przetłumaczyć te ikony na język polski.
Być może już niedługo pojawi się uaktualnienie wersji 3, która będzie wyświetlała menu.
Zrzut ekranu z wersji 2 zamieszczam pod spodem, abyście wiedzieli o co chodzi:


Piąta linia mojej konfiguracji, wyłącza aktywne linki z "Kolorowanego składni" kodu, aby nie można na nie "klikać".

Na bazie drugiego linku dokonałem konfiguracji: Dzięki temu zmieniłem wygląd - szablon "Kolorowania składni".
Można wybierać z pośród kilku dostępnych szablonów.

Krok IV (wady i zalety obu metod z Kroku II):

Wady opiszę na przykładzie pierwszego "Kolorowania składni" tego posta, tym z 34 liniami.

Gdy używamy metody: <script /> method, każde wystąpnie </script>, zamyka "Kolorowanie składni", obojetnie czy było czy nie było: ]]>.
Jest to problem, gdyż nie można umieszczać "Kolorowania składni" z otwartym <script> i zamknietym </script>. A jak widzicie w moim przypadku jest użyte otwarcie i zamknięcie script. Taki jest kod w "Kolorowaniu składni" i taki musi pozostać.
Zdecydowałem się w takim razie na użycie w moim mniemaniu metody trudniejszej, czyli metody: <pre> method. I wszystko byłby ładnie, ale musiałem dokonać zamiany kodu JavaScript, na kod JavaScript z encjami.
Poszło bez problemu.

Metoda: <pre> method się sprawdza, poza jednym ale: jak ładuję się strona www - mój blog, przez krótką chwilę widzicie, czysty tekst bez "Kolorowania składni", dopiero po 1 sekundzie zamienia się na kod JavaScript "Pokolorowany".
Metoda: <script /> method nie ma tego problemu, gdy strona się ładuję nic się nie wyświela, po załadowaniu wyświetla się od razu "Pokolorowany" kod - też to możecie zaobserwować na moim blogu w tym post-cie, w każdym innym "Kolorowaniu składni", poza tym z 34 liniami.
W zasadzie w przypadku metody: <pre> method, też można obejść ten problem, poprzez nie zamienianie kodu na kod z encjami, ale jest to ryzykowane, bo "Pokolorowany" kod, może nie odpowiadać rzeczywistości. W moim przypadku gdy testowałem tego posta, jak nie dokonałem zamiany kodu JS na kod JS z encjami, pierwsze trzy linie nie odpowiadały rzeczywistości, brakowało na końcu znaków "/". Niestey nie ma na to rozwiązania - w każdym bądź razie narzędzie SyntaxHighlighter, tego nie umożliwia.

Podsumowanie - Moim Zdaniem: Używamy zawsze metody: <script /> method, a gdy jest konieczność, np. zamykania znacznika script, korzystamy z metody: <pre> method zawsze z kodem zamienionym na encje, pamiętając równocześnie o niedogodności związenej z ładowaniem strony www, o której wspominałem wcześniej.

Trzeba być elastycznym w doborze metod!!!

Na strony Twórcy narzędzia są opisane wady i zalety (o których wspominałem i inne nie poruszone w tym post-cie) każdej metody.
Akapit - <pre> method - PROBLEMS
Akapit - <script /> method - PROBLEMS
Patrz tutaj (język ang.)



Każdy mój post, dotyczący w mniejszym lub większym stopniu programowania internetowego jest zawsze kompatybilny z IE od wersji 7, z Firefox od wersji 3.6.3, z Opera od wersji 9.63, z Safari od wersji 5.x i z Chrome od wersji aktualnej