LABORATORIUM 9


PROCESY

Proces jest wykonywaniem programu. Procesy mają swoje identyfikatory (PID) będące liczbami naturalnymi. Zadanie (job) jest pojedynczym procesem lub całym potokiem (ciągiem współbieżnych procesów połączonych wejściem/wyjściem standardowym) uruchomionym z linii poleceń. Zadania uruchamiane w danym terminalu tekstowym jako identyfikatory otrzymują początkowe liczby naturalne (w poleceniach są one poprzedzane znakiem %).

W opisach niżej używanych poleceń należy zwrócić uwagę na to, czy argumentem powinien być PID procesu, czy identyfikator zadania.
ZADANIA

Zad. 1
Przeczytać opis polecenia zewnętrznego ps. Wypróbować je: a) ps ; b) ps x . Zwrócić uwagę na procesy bez terminala sterującego (oznaczone "?"). Otworzyć drugie okno tekstowe, ponowić próbę.

Zad. 2
W opisie bash'a przeczytać rozdział KONTROLA ZADAŃ (JOB CONTROL), opisy poleceń wewnętrznych bg, fg, jobs, kill i trap oraz opisy działania kombinacji kluczy ctrl-c, ctrl-z i ctrl-y. Utworzyć kilka (2-3) egzemplarzy skryptu wyświetlającego w pętli nieskończonej jakiś napis co kilka sekund:
   while true
   do
      echo ........  #jakiś napis
      sleep .......  #liczba sekund
   done
Uruchomić w tle kilka procesów współbieżnych (na podstawie utworzonych skryptów) przy użyciu polecenia o postaci
             skrypt1 & skrypt2 & skrypt3 &
Wypróbować przy użyciu: a) tego samego okna tekstowego; b) drugiego okna tekstowego działanie poleceń bg, fg, kill -9 ... PID procesu oraz powyższych kombinacji kluczy


W poniższych dwóch zadaniach pokazane jest działanie funkcji fork() (tworzącej nowy proces) oraz funkcji execl() (przenoszącej nowy proces do innego pliku z programem).
Zad. 3
Utworzyć, skompilować i uruchomić program w języku C:
   #include <stdio.h>
   #include <unistd.h>
   #include <sys/types.h>
   
   main() {
      if (fork()==0)
         while (1) {
            printf("Proces potomny %d\n",getpid());
            sleep(3);
         }
      else while (1) {
              printf("Proces rodzicielski %d\n",getpid());
              sleep(5);
           }
      return;
   }
Przy użyciu polecenia ps x podanego w drugim oknie tekstowym sprawdzić identyfikatory obu uruchomionych procesów, następnie po kolei usunąć je przy użyciu polecenia o postaci kill -9 identyfikator .

Zad. 4
Utworzyć dwa programy w języku C:
   --------
   rodzic.c
   --------

   #include <stdio.h>
   #include <unistd.h>
   #include <sys/types.h>

   main() {
      if (fork()==0)
         execl("... pełna nazwa ścieżkowa pliku potomek ...","potomek",NULL);
      else while (1) {
              printf("Proces rodzicielski\n");
              sleep(5);
           }
   }

   ---------
   potomek.c
   ---------

   #include <stdio.h>

   main() {
      while (1) {
         printf("To ja, potomek, wykonuje swoj program\n");
         sleep(3);
      }
   }
Skompilować je tak, aby wynikiem kompilacji pierwszego programu był plik o nazwie rodzic, a drugiego - potomek. Uruchomić program rodzic, a następnie postępować tak, jak w przypadku poprzedniego zadania.


Jeśli terminal tekstowy, w którym są wykonywane jakieś procesy, zostanie wyłączony, przez domniemanie wszystkie te procesy zostaną w tym momencie unicestwione. Jeśli użytkownik chce, aby pomimo zamknięcia terminala procesy te dalej się wykonywały (jako procesy bez terminala sterującego), może to osiągnąć na kilka sposobów. Sposoby te sprowadzają się do ustawienia pułapki (trap) na sygnały wysyłane do procesów w chwili zamykania terminala:
        SIGHUP - jest sygnałem wysyłanym w przypadku kończenia sesji pracy
                 przez podanie polecenia exit

        SIGTERM - jest sygnałem generowanym w przypadku usunięcia terminala
                  (zamknięcia okna przyciskiem X)
Uwaga: jeśli argumentem polecenia ma być identyfikator sygnału, może on być podawany zarówno w formie liczbowej, jak i mnemonicznej. Przykładowo polecenie usuwające bezwarunkowo proces:
            kill -9 .... (PID procesu)
może też być podane jako:
            kill -SIGKILL .... (PID procesu)
lub, krócej:

            kill -KILL .... (PID procesu)
Zad. 5
Przeczytać opis polecenia nohup. Uruchomić przy jego użyciu (w tle) skrypt z zadania 2. Wyłączyć okno tekstowe (exit), otworzyć ponownie i sprawdzić (ps x), że proces nadal działa, ale bez terminala sterującego. Obejrzeć kilkukrotnie zawartość automatycznie utworzonego pliku o nazwie nohup.out . UWAGA: po wykonaniu zadania usunąć ten proces oraz plik nohup.out , aby uniknąć zablokowania konta po pewnym czasie.

Zad. 6
Analogiczny efekt uzyskać dopisując na początku treści skryptu polecenie
      trap "" SIGHUP
i uruchamiając skrypt poleceniem o postaci skrypt > plik & UWAGA: aby proces "przeżył" wyłączenie okna tekstowego przyciskiem, należy dopisać na początku treści skryptu polecenie
      trap "" SIGTERM
Zad. 7
Utworzyć skrypt z jednym argumentem, który będzie wykonywany w tle, będzie odporny na wylogowanie się właściciela i zamknięcie terminala tekstowego, i który co pół minuty będzie wysyłał komunikat "ODDAJ MI 100 PLN !" do użytkownika o nazwie $1 (zalogowanego, przyjmującego komunikaty).
UWAGA: wypróbować działanie powyższego skryptu po zalogowaniu się przez SSH na sigmę, w porozumieniu z innymi uczestnikami zajęć.