instrukcja

Transkrypt

instrukcja
04
Metodyka i Techniki Programowania
Procesy i wątki
dr inż. Jacek Dańda
2013.03.18
Wszystkie ćwiczenia należy wykonać w systemie UNIX/Linux.
Lista procesów
Opisz efekt działania komendy ps. Opisz następujące opcje komendy ps: -a, a, -e, -f, -u, -x. Co
oznaczają następujące pola: CMD, PID, PPID, STAT?
Procesy w tle
Uruchom program sleep z parametrem 600. Wyślij do niego sygnał TSTP. Jak wysłać taki sygnał?
Uruchom jeszcze raz program sleep z parametrem 200 i również wyślij do niego TSTP, a następnie
uruchom polecenie „sleep 100 &”. Co oznacza „&”? Wyświetl swoje zadania za pomocą jobs. Które
zadania się wykonują, a które nie? Użyj poleceń bg i fg, żeby odpowiednio uruchamiać zadania w tle
i na pierwszym planie.
Sygnały
Do czego służy polecenie kill? Uruchom kill z opcją –l. Spróbuj wysłać sygnały HUP, INT, TSTP,
QUIT, KILL, TERM za pomocą tego polecenia do programu sleep uruchomionego w tle. Następnie
uruchom drugie okno konsoli, uruchom w nim program vi, a następnie z pierwszego okna spróbuj
wysłać do niego sygnał INT. Czy vi reaguje tak samo na INT, jak sleep? Napisz program, który
przechwytuje sygnał INT i nie przerywa swojego działania (użyj signal()).
fork()
Uruchom program. Wyjaśnij kod i działanie programu.
#include <stdio.h>
#include <unistd.h>
int main()
{
int a;
switch((a=fork()))
{
case -1:
/* fork nie zadzialal */
printf("Ups.\n");
break;
case 0:
/* kod procesu potomnego */
printf("Dzieciak: rodzicem jest proces o pid=%d\n", getppid());
printf("Dzieciak: moj PID=%d\n", getpid());
sleep(60);
printf("Dzieciak: do widzenia.\n");
_exit(0);
break;
default:
printf("Rodzic: fork zwrocil PID dzieciaka: %d\n", a);
sleep(30);
printf("Rodzic: do widzenia.\n");
_exit(0);
break;
}
return 0;
}
Uruchom program w tle. Sprawdź, ile powstało procesów o tej nazwie, do której skompilowałeś
program, jakie mają identyfikatory PID i PPID. Zwróć też uwagę na PID shell’a. Poczekaj na
zakończenie rodzica i sprawdź jeszcze raz. Czy proces potomny powinien kończyć się po rodzicu?
Kiedy fork() może zwrócić -1?
wait()
Program z powyższego ćwiczenia zmodyfikuj tak, żeby rodzic przy pomocy wait() czekał na
zakończenie procesów potomnych. Zakończ proces potomny przy pomocy kill. Wykorzystaj
WIFEXITED() i WTERMSIG(), żeby wyświetlić w sekcji rodzica informacje o zakończeniu procesu
potomnego. Zamiast wait() użyj waitpid(); efekt działania programu ma być taki sam.
execl()
Uruchom program. Wyjaśnij kod i działanie programu.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("Program do podmiany kodu.\n");
sleep(2);
printf("Podmieniam kod.\n");
execl("/bin/ls", "ls", 0);
execl("/bin/date", "date", 0);
printf("Czesc.\n");
return 2;
}
Czy drugie wywołanie execl() ma sens? Usuń „/bin/” w ścieżkach, skompiluj, wykonaj program.
Co się zmieniło?
Umieść w bieżącym katalogu plik z kodem (poniżej), który skompiluj do nazwy „nowy”. Linijkę
execl("/bin/ls", "ls", 0); zamień na execl("nowy", "totamto", 0); . Uśpij program po
podmianie kodu. Użyj ps, co się zmieniło?
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("Ide spac.\n");
sleep(15);
printf("Koncze.\n");
return 0;
}
Wątki
Skompiluj
#include
#include
#include
poniższy kod (z opcją –pthread), wykonaj i wytłumacz go.
<stdio.h>
<pthread.h>
<pthread.h>
struct dane {
int numer;
int czas;
};
void *fun_watku(void *dane_przekazane_do_watku){
struct dane *d = (struct dane *) dane_przekazane_do_watku;
int i;
printf("Poczatek watku nr %d.", d->numer);
for (i=0; i<d->czas; i++)
{
printf("Watek: spie w petli %i.\n", i+1);
sleep(2);
}
printf("Koniec watku nr %d\n", d->numer);
return;
}
int main(){
pthread_t watek_id;
int i;
struct dane a;
a.numer = 1;
a.czas = 5;
printf("Uruchamiam watek.\n");
pthread_create(&watek_id, NULL, fun_watku, &a);
sleep(1);
for (i=0; i<5; i++)
{
printf("Glowny: spie w petli %i.\n", i+1);
sleep(3);
}
printf("Koniec programu.\n");
return 0;
}
Zmień powyższy kod tak, aby wątek spał łącznie 20 sekund. Sprawdź, co się dzieje. Następnie
wymuś, żeby program główny czekał na zakończenie wątku przy pomocy pthread_join().
Napisz program, który co sekundę próbuje wyświetlić bieżącą datę i jednocześnie, niezależnie od
programu głównego, co sekundę wysyła pakiety ICMP do adresu IP będącego argumentem
wywołania programu. Użyj system() oraz sprintf().

Podobne dokumenty