Zad.1. (2 punkty - na zajęciach)
Napisz program w ANSI C wykonujący jakąś trywialną operację (np. ++i;
)
w nieskończonej pętli. Skompiluj i uruchom program, a następnie programem
top
sprawdź, czy Twój program pokazuje się w czołówce programów
wykorzystujących cykle obliczeniowe komputera. Przed przejściem do
dalszych prac zabij program klawiszem Ctrl-C
. Dodaj w pętli małe
opóźnienie (sleep(1);
, a najlepiej nanosleep();
z opóźnieniem np. 10
milisekund) i upewnij się, że po uruchomieniu tego programu nie pojawia się
on już na szczycie listy top
.
Domyślna częstotliwość odświeżania programu top
jest mała, spróbuj ją
zmienić korzystając z dostępnej pomocy programu. Zapisz co należało dodać
do wywołania programu.
Zad.2. (4 punkty - na zajęciach, lub 2 punkty - w domu)
Dodaj w stworzonym programie przechwytywanie sygnału/ów, i wykorzystując
sygnały: SIGALRM
, SIGTERM
, SIGUSR1
, SIGUSR2
wypróbuj następujące
reakcje na sygnał:
(a) całkowite ignorowanie sygnału,
(b) wyświetlenie komunikatu i zakończenie pracy programu,
(c) wyświetlenie komunikatu i powrót do wykonywania programu,
(d) wstrzymywanie odbierania sygnału plus okresowe wznawianie jego
odbierania na krótkie okresy czasu
(na przykład, przed uruchomieniem pętli wstrzymaj odbieranie sygnału, i co 1000 iteracji odblokuj, i natychmiast ponownie wstrzymaj odbieranie tego sygnału, z odpowiednimi komunikatami przed i po odblokowaniu).
W raporcie wklej instrukcje programu deklarujące poszczególne reakcje na sygnał, i podsumuj uzyskane wyniki.
Uwaga1: do wstrzymywania/odblokowania odbierania sygnałów można użyć
funkcji sighold/sigrelse
. Na Linuksie kompilacja programów z tymi
funkcjami wymaga zdefiniowania makra _XOPEN_SOURCE
z wartością >= 500.
Uwaga2: funkcje signal/sigset/sighold/sigrelse
należą do
tradycyjnego interfejsu obsługi sygnałów. Ich użycie jest bardzo proste,
ale mają szereg wad (patrz man signal
). Nowoczesny interfejs obsługi
sygnałów składa się z szeregu funkcji z których główną jest sigaction
.
Uwaga3: funkcje obsługi sygnałów (tzw. handlery) powinny być pisane w bardzo szczególny sposób. Powinny być minimalne, bardzo krótkie i bardzo niezawodne, aby nie dopuścić do wygenerowania jakiegokolwiek błędu i innego sygnału w trakcie wykonywania handlera. Praktycznie, treść handlera powinna być ograniczona do: wyświetlenia komunikatu o zaistniałej sytuacji, ustawienia wartości zmiennej globalnej, ewentualnych akcji ratunkowych, takich jak zamknięcie zapisywanych plików, i powrotu z handlera, lub zatrzymania programu. Handler nie powinien realizować żadnych funkcji programu.
Zad.3. (2 punkty - w domu)
Zapoznaj się z narzędziami umożliwiającymi odczyt pseudosystemu plików
/proc
(man proc
). W systemie Solaris pliki w tym systemie mają
specyficzny format, i do ich odczytu i dekodowania treści służy odpowiedni
zestaw programów.
W systemie Linux pliki w /proc
maja formaty tekstowe i można je
odczytywać (a w konkretnych przypadkach również zapisywać) zwykłymi
narzędziami do operacji na plikach tekstowych, jak: cat
, grep
, itp.
Uruchom program z poprzedniego punktu przechwytujący/ignorujący wybrane sygnały. Następnie sprawdź tablicę akcji przypisanych poszczególnym sygnałom dla uruchomionego procesu. W raporcie podaj polecenia wyświetlające informację o obsłudze sygnałów: (a) dla systemu Linux, (b) dla systemu Solaris. W każdym punkcie wklej otrzymane wyniki i krótko wyjaśnij znaczenie wyświetlanych informacji.
Zad.4. (2 punkty - w domu)
Stwórz potok trzech poleceń, tak aby pierwszy program w nieskończonej pętli
wypisywał jakiś tekst. Za pomocą odpowiedniego programu operującego na
strukturze /proc
zbadaj otwarte pliki każdego z procesów uczestniczących
w potoku. Czy wyłącznie na podstawie uzyskanych w ten sposób informacji
można odtworzyć kolejność występowania poleceń w potoku? Jeśli tak to w
jaki sposób? W raporcie odpowiedz na te pytania oddzielnie: (a) dla
systemu Linux, (b) dla systemu Solaris.