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.