Systemy operacyjne ćwiczenia 1 procesy, wątki, polecenia UNIXa. 1. Na ćwiczeniach będziemy: pisać skrypty powłoki UNIXa (tcsh, bash, Perl), programować w C (pierwsze 6-8 zajęć), Javie, i Adzie (kolejne 6-7 zajęć). Javę (SDK 6) można ściągnąć z sieci ze stron http://java.sun.com Natomiast Adę (kompilator GNAT) ze strony http://sourceforge.net/projects/gnuada/files/ C: program przykład.c Kompilacja: gcc przyklad.c o przyklad Uruchomienie:./przyklad Do siebie można przekopiować plik przez wget 2. System współbieżny (concurrent) to taki w którym wiele programów (lub, ogólniej, zadań) może wykonywać się równocześnie na jednym komputerze. Może być to realizowane na dwa sposoby: możemy mieć do czynienia z wieloma procesorami, na których programy wykonują się faktycznie równocześnie (może być wiele procesorów w jednym komputerze), i wtedy mówimy o systemie równoległym (parallel) lub z iluzją równoległości polegającą na tym, że system operacyjny często przełącza kontekst (ang. context switch) pomiędzy wykonującymi się programami. Mechanizm ten nazywa się multitasking. Z punktu widzenia programowania (przynajmniej na użytek tych zajęć) nie będzie dla nas istotne, czy mamy równoległość, czy nie. Mamy współbieżność, i tyle. 3. W poprzednim punkcie wspomniałem o wielu programach czy zadaniach (tasks). Działające zadania mogą być procesami (ang. process) lub wątkami (ang. thread). Procesy mają osobną od siebie przestrzeń adresową w pamięci (gwoli prawdy pamięć procesów jest rozłączna, gdy procesy wykonują się w trybie użytkownika, mogą być także w trybie jądra, w czasie gdy wykonują wywołania systemu operacyjnego, wtedy mają dostęp do całej pamięci) i osobne otwarte pliki (w UNIXIE każdy proces ma tzw tablicę deskryptorów otwartych plików, deskryptory w różnych procesach mogą wskazywać na ten sam plik, nawet dwa różne deskryptory w tym samym procesie mogą wskazywać na ten sam plik, patrz rysunki na http://www.cim.mcgill.ca/~franco/opsys-304-427/lecturenotes/node27.html). Wątki natomiast współdzielą przestrzeń adresową i tablicę otwartych plików. Procesy i wątki tworzą układ hierarchiczny, tzn każdy proces zawiera pewną ilość wątków. Na maszynie wieloprocesorowej wątki w ramach jednego procesu mogą być przydzielone na różne procesory. W Windowsie można to obejrzeć wątki przez TaskManager->Processes i wybrać w View->Select Columns opcję Thread Count. Więcej danych można zaobserwować przez Process Explorera. W Linuxie/Unixie wpisując top dostaniemy listę procesów z których każdy ma unikatowy identyfikator PID. Jeśli wpiszemy top T to dostaniemy listę wątków (na elfie może być out of memory) z których dwa mogą mieć ten sam PID jeśli należą do tego samego procesu. To samo można zrobić operacją ps (spróbować ps -Tfe sort more, ps -fe sort more). 4. Zarządzanie wątkami: wątki to mechanizm zaimplementowany w systemie operacyjnym. W różnych językach programowania są różne API pozwalające programistom uruchamiać wątki i zarządzać nimi. Np. dla C++ jest wiele takich
obiektowych API (choć nie ma jednego standardowego), z kolei dla C pod UNIXEM mamy standard POSIX. W Javie podstawowym API jest klasa Thread i interfejs Runnable. W Adzie jest to mechanizm tasków. 5. Przykład w Javie: Wątek to obiekt klasy Thread. Własne wątki (czyli wykonujące jakiś zdefiniowany przez użytkownika kod w ramach swojego działania) można definiować na dwa sposoby: można tworzyć klasę dziedziczącą po klasie Thread lub implementować interfejs Runnable. Omówię (jako bardziej skomplikowany) ten drugi sposób: W klasie implementującej interfejs Runnable należy umieścić metodę run(). Jest to metoda w której ma się znaleźć to, co będzie wykonywane w ramach działania wątka. Poza tym w programie (w obiekcie implementującym Runnable lub gdzie indziej) ma znaleźć się obiekt klasy Thread. W programie powinniśmy: I) utworzyć obiekt naszej klasy implementującej Runnable, II) utworzyć obiekt Thread, podając mu obiekt utworzony w poprzednim punkcie jako argument do konstruktora (wątek się utworzy ale będzie zawieszony), kroki I i II można (choć nie trzeba), robić równocześnie, obiekt Thread można stworzyć w konstruktorze obiektu tworzonego w punkcie I, III) wywołać start() dla obiektu Thread (wątek zacznie wykonywać swojego runa w sposób asynchroniczny). Zadanie 1: uruchomić i zrozumieć przykład Watki.java (najlepiej w NetBeansie). Zadanie 2: modyfikując ten przykład, napisać program, w którym będzie 11 wątków. 10 z nich powinno być ponumerowanych od 0 do 9, wątek i dla i od 0 do 9 powinien wypisywać kolejne liczby naturalne dające resztę i przy dzieleniu przez 10. Ostatni wątek powinien oczekiwać na wciśnięcie klawisza (niech będzie ustalony klawisz i 'Enter') i przerwać program. Najlepiej stworzyć klasę NumberThread i StopperThread (obie implementujące Runnable). W każdej z nich powinno być pole Thread, a w klasie NumberThread dodatkowo pole int zawierające numer wątku. 6. Przykład w C: Operacja fork() tworzy proces potomny dla danego procesu. Domyślnie wykonuje on ten sam kod co dany proces. Rozróżnić w któremu procesie jesteśmy można przez wartość zwracaną przez fork(). W procesie dziecku jest to 0 a w procesie rodzicu jest to pid (identyfikator dziecka). 7. Każdy proces ma swój numer identyfikator. Jest to tak zwany numer pid. Można go zaobserwować przez top lub ps (man ps różne opcje). Ponadto każdy proces ma swojego rodzica (numer PPID). W ten sposób procesy tworzą drzewo. Pod UNIXem jego korzeń to systemowy proces init, który ma pid 1. Z kolei pod Windowsem procresy nie tworzą drzewa tylko las (zaobserwować to). 8. Procesy mają także swoje priorytety. Pod Windowsem można zaobserwować je w Process Explorerze, a pod UNIXem przez top lub ps. Co ciekawe w Windowsie wyższa liczba oznacza proces bardziej uprzywilejowany, podobnie na UNIXie IRIX64 (elf). Z kolei na virgo (Linux) jest odwrotnie.
Pod UNIXem można zmienić priorytet procesu poleceniem renice: Zadanie 3: wpisać top, wcisnąć Ctrl+Z, zrobić ps (znaleźć pid topa), wpisać renice -n 5 -p pid_topa, wpisać fg i zobaczyć jak zmienił się priorytet topa. Pod Linuxem (virgo) składnia renice jest trochę inna. Powtórzyć na virgo analogiczną sekwencję poleceń (man renice). Zadanie 4: napisać (pod Windowsem) program w Javie, który będzie zajmował cały czas procesor (np. będzie wykonywał polecenia arytmetyczne w długiej pętli). Uruchomić dwie instancje tego programu w dwóch oknach command line. Przeanalizować procentową zajętość procesora przez oba programy. Zbadać co się stanie, gdy priorytet jednego z programów zmniejszymy do 6. Zbadać wpływ ustawienia System->Zaawansowane- >Opcje wydajności->optymalizuj wydajność. 8. Polecenia Systemu UNIX (materiały na stronie http://wazniak.mimuw.edu.pl/index.php? title=systemy_operacyjne. Laboratorium 2-4) A) passwd zmiana hasła B) finger zalogowani użytkownicy, finger username informacje o użytkowniku Zadanie 5: jak zmienić tekst no plan na inny? C) id identyfikator użytkownika, grupa, do której należy użytkownik D) uptime informacje o pracy systemu E) uname (-a) informacje o systemie F) ls wyświetlenie zawartości katalogu (przetestować opcje -a i -l). Od kropki zaczynają się pliki ukryte. l link, d katalog, - plik Zadanie 6: i) wyświetlić pliki zaczynające się od literki 'a' w katalogu /etc ii) wyświetlić pliki zaczynające się od '.' w katalogu etc (wykorzystać polecenie grep, które wyświetla tylko linie kodu zawierające zadany łańcuch np. ls grep x) Uwaga: / to katalog główny, natomiast ~ to katalog domowy bieżącego użytkownika. ~username to katalog domowy zadanego użytkownika. Natomiast. to katalog bieżący a.. to katalog o jeden poziom wyżej. G) cd zmiana bieżącego katalogu (spróbować wpisać samo cd) H) mkdir zakładanie katalogu I) rmdir usunięcie katalogu (-r rekurencyjnie, -p usuwa podane nadkatalogi danego katalogu jeśli staną się puste) J) przesłanie wyniku działania jakiejś instrukcji do pliku > nazwapliku zawsze tworzy nowy plik o podanej nazwie >> nazwa pliku dokatenowuje do istniejącego pliku jeśli taki jest, tworzy, jeśli nie ma
K) cp kopiowanie pliku cp -r kopiuje rekurencyjnie (z podkatalogami), oczywiście przy okazji można zmienić nazwę pliku, L) mv przeniesienie pliku np. z jednego katalogu do innego, możliwa jest tu zmiana nazwy na inną M) rm usunięcie pliku (-r rekurencyjnie, -f bez pytania, niebezpieczne) Zadanie 7: Utworzyć w katalogu domowym plik o nazwie mojplik zawierający skatenowany wynik działania poleceń ps i ls w katalogu domowym. Utworzyć podkatalog mojkatalog i przenieść tam mojplik zmieniając mu przy okazji nazwę na lsps. Usunąć plik i katalog. Uwaga: polecenie scp pozwala kopiować pliki z i na zdalny host. N) Wildcardy dla poleceń kopiowania: dowolny znak?, dowolny ciąg znaków * [abc], [0-9] dowolny znak z podanego zakresu [^abc], [^0-9] dowolny znak spoza podanego zakresu Zadanie 8: Skopiować wszystkie pliki zaczynające sie od literki a i nie mającej jako drugiej literki u z katalogu /etc do założonego uprzednio podkatalogu nowy w katalogu domowym. Usunąć spośród nich wszystkie pliki nie kończące się na cyfrę. Jaki plik zostanie? O) whereis wyszukuje pliki binarne, źródłowe i man związane z programami, np.: whereis ls (-m tylko man, -b tylko binarne, -s tylko źródłowe). P) who zalogowani użytkownicy Zadanie 9: Znaleźć polecenie które pozwala określić datę ostatniego logowania zadanego użytkownika. Q) find wyszukuje pliki rekurencyjnie poczynając od zadanego katalogu, np. find katalog -name plik. find katalog -name plik -type d (lub l lub f) wyszukuje odpowiednio katalogów, dowiązań lub zwykłych plików -size +n (co najmniej n) lub -n (co najwyżej n) bloków o rozmiarze 512 kb, mogą być to inne jednostki np. c bajty, np. find ~ -size +20000c -exec polecenie {}\; {} to miejsce w które do polecenia są wstawione znalezione pliki, np. find ~ -name *.o -exec rm {}\; Użycie jako katalogu / w wyszukiwaniu nie jest generalnie najlepszym pomysłem (będzie długo trwało). Zadanie 10: Skopiować wszystkie pliki na literkę 'm' z katalogu /etc o rozmiarze pomiędzy 3000 bajtów a 5000 bajtów do uprzednio założonego katalogu bbb w katalogu domowym. R) chmod zmiana praw dostępu chmod [ugo][+-=][rwx] pliki u user, g grupa, o inni (patrz ls -l) + dodanie praw, usunięcie, = ustawienie
r odczytu, w zapisu, x uruchamiania możliwa reprezentacja liczbowa chmod [0-7][0-7][0-7] 4 odczyt, 2 zapis, 1 uruchamianie pierwsze pole dla siebie, drugie dla grupy, trzecie dla pozostałych Zadanie 11: utwórz nowy pusty plik (polecenie touch plik) sprawdź jakie są prawa dostępu. Dodaj prawo zapisu dla grupy a odejmij prawo zapisu dla właściciela, dodaj prawo wykonywania dla wszystkich użytkowników. Sprawdź czy właściciel ma teraz prawo zapisu (spróbuj coś do pliku zapisać). S) ln plik link stworzenie dowiązania Zadanie 12: i) utworzyć w katalogu domowym plik o nazwie plik1 w którego treści jest wynik działania polecenia ls. Założyć katalog o nazwie a. Utworzyć w nim link do pliku plik1. Utworzyć w katalogu domowym katalog b. Przenieść do niego plik1. Na co wskazuje link w katalogu a? Skasować plik na który wskazuje link. Na co teraz wskazuje link z katalogu b? ii) utworzyć plik o nazwie plikls, w którym jest wynik polecenia ls w katalogu domowym. Wykonać polecenia ln plikls link, cp link link2. Ile mamy fizycznie kopii pliku plikls? Zmodyfikować (np. przez joe) plikls i link2 (niezależnie od siebie). Co jest w pliku link? Domyślnie jest tworzone dowiązanie twarde, które 'podpina' plik w drzewie katalogów w innym miejscu. Własności tej nie ma dowiązanie miękkie (które działa jak skrót z Windowsów): ln s plik link Zadanie 13: powtórzyć powyższe postępowanie z dowiązaniem miękkim. T) Wysłanie sygnału do procesu kill -n pid -2 sygnał interrupt (Ctrl+C) -9 sygnał kill (bezwarunkowe przerwanie procesu) kilall nazwa (wysyła sygnał kill do wszystkich procesów o zadanej nazwie) U) Polecenie można uruchomić w tle przez opcję &: polecenie & aktualnie wykonywany program też można przenieść w tło przez zatrzymanie go (Ctrl+Z), to spowoduje że przerwie swoje działanie, a potem wpisanie bg, proces będzie wykonywał się w tle. Z kolei fg przenosi proces z tła na pierwszy plan. Zadanie 14: wyszukać wszystkie pliki na elfie zawierające w nazwie słowo buka. Wynik ma się zapisywać do pliku buki w swoim katalogu domowym. Wyszukiwanie ma wykonywać się w tle, a jego priorytet ma być równy 5. Komunikaty o błędach zapisywać do pliku errors. Uwaga: w bash przekierowanie błędu (stderr) to 2>. Natomiast w csh i tcsh nie można przekierować samego błędu. Trzeba zrobić (polecenie > /dev/tty) >& /dev/null (lub plik o nazwie errors). >& to przekierowanie i błędu i stdout. jobs wyświetla wszystkie aktualnie kontrolowane procesy (+ to zadanie, które jest defaultowe dla poleceń fg i bg).
V) polecenie1 && polecenie2 polecenie 2 uruchomi się gdy polecenie1 zwróci do powłoki 0 (zakończy się sukcesem) polecenie1 polecenie2 polecenie 2 uruchomi się gdy polecenie1 zwróci do powłoki co innego niż 0 (zakończy się niepowodzeniem) polecenie1; polecenie2 polecenia uruchomią się sekwencyjnie (polecenie1; polecenie2) & - polecenia uruchomią się sekwencyjnie w tle W) cat katenacja plików cat plik1 plik2 > plik3 cat plik wypisuje plik na standardowe wyjście Zadanie 15: co robią operacje i) cat ii) cat > plik iii) cat >> plik iv) cat < plik v) cat << plik vi) cat < plik >plik2 Uwaga: jeśli polecenie cat uruchomimy bez podawania pliku, to cat będzie pobierał dane ze standardowego wejścia. Uwaga 2: znak End-of-file to w UNIXie Ctrl + D 9. W domu: A) przerobić dokładnie http://wazniak.mimuw.edu.pl/index.php?title=sop_lab_nr_2 http://wazniak.mimuw.edu.pl/index.php?title=sop_lab_nr_3 http://wazniak.mimuw.edu.pl/index.php?title=sop_lab_nr_4 do przetwarzania potokowego. B) Przerobić przykład przyklad.c tak, aby proces potomny żył dłużej niż proces rodzica. Kto się stanie wówczas jego rodzicem? Zbadać to