Programowanie systemowe – procesy i wątki

ćwiczenia laboratoryjne



Przydatne biblioteki i funkcje

Przydatne stałe wartości



Zadania


Zadanie 1. Przed uruchomieniem postaraj się odgadnąć co wyświetli program w C:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>


int main() {
 printf("pierwszy napis\n");
 fork();
 wait(NULL);
 printf("drugi napis\n");
 fork();
 wait(NULL);
 printf("trzeci napis\n");
 return 0;
}
Następnie skompiluj, uruchom oraz sprawdź, co zostanie wyświetlone. Uzasadnij działanie tego programu oraz sprawdź co się stanie jeśli usuniesz wait(NULL) z kodu programu.

Zadanie 2. Utwórz program, który będzie działał w nieskończonej pętli. Jeżeli do procesu uruchamiający skrypt zostanie wysłany sygnał SIGINT, powinien wyświetlać napis: Jestem nieśmiertelny oraz swój identyfikator procesu. Jeżeli do procesu uruchamiający skrypt zostanie wysłany sygnał SIGHUP, skrypt powinien przestać reagować na sygnał SIGINT.
Podpowiedź: Przykładowy program obsługujący sygnał:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handleSignal(int s) {
 write(STDOUT_FILENO, "HELLO", 5);
}

int main() {
 signal(SIGINT, handleSignal);
 return 0;
}

Zadanie 3. Napisz program, który utworzy proces potomny.
Proces potomny powinien wyświetlać swój identyfikator oraz identyfikator procesu nadrzędnego oraz "wylosowaną" liczbę z zakresu [1; 50] oraz zakończyć swoje działanie w momencie, gdy wylosowana liczba będzie podzielna przez 5.
Proces nadrzędny, powinien poczekać, aż jego proces potomny zakończy swoje działanie i wypisać komunikat w którym wypisze swoje id, a następnie zakończyć program.
Podpowiedź: W celu losowania liczb możesz użyć biblioteki: <time.h>, <stdlib.h> oraz funkcji rand.

Zadanie 4. Napisz program, który utworzy dwa procesy potomne.
Procesy potomne powinny działać w nieskończonej pętli wyświetlać swój identyfikator oraz identyfikator procesu nadrzędnego.
Proces nadrzędny powinien, co jakiś czas, "losować" liczbę [1; 50] i zakończyć pracę pierwszego jeśli wylosowana zostanie liczba mniejsza niż 10 oraz drugiego procesu jeśli większa niż 40. Po "zabiciu" dwóch procesów powinien skończyć swoje działanie.
Podpowiedź: W celu losowania liczb możesz użyć biblioteki: <time.h>, <stdlib.h> oraz funkcji rand.

Zadanie 5. Napisz program, który utworzy dwa procesy potomne, które będą komunikować się poprzez plik FIFO.
Pierwszy proces potomny ("dostawca") powinien komunikować co jakiś czas wysyłać poprzez potok nazwany "losowo" wybraną nazwę produktu.
Drugi proces potomny ("magazynier") powinien nadsłuchiwać potok nazwany, odbierać nadesłane nazwy produktów i zapisywać je kolejno w pliku tekstowym.
Proces główny po upływie określonego czasu powinien zakończyć zadanie.
Podpowiedzi:
Przykładowa deklaracja listy możliwych produktów:
const char *products[] = {"Mleko", "Chleb", "Masło", "Ser", "Jabłka", "Banany", "Czekolada", "Kawa", "Herbata", "Cukier"};
Otwarcie i zamknięcie potoku nazwanego: open (z flagą O_RDONLY lub O_WRONLY), close.
Wysyłanie i odebranie wiadomości do/z potoku nazwanego: write, read.

Zadanie 6. Napisz program, który pobierze z pliku liczbę n i utworzy n wątków, które, co jakiś czas, będą wyświetlały swój identyfikator oraz "wylosowaną" liczbę z przedziału [1; 50]. Każdy wątek powinien zakończyć swoje działanie w momencie, gdy wylosowana liczba będzie podzielna przez 5. Proces główny powinien zakończyć działanie, gdy każdy wątek zakończy działanie.
Podpowiedź 1: W celu losowania liczb możesz użyć biblioteki: <time.h>, <stdlib.h> oraz funkcji rand.
Podpowiedź 2: Przykładowy program tworzący wątek:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *myThread(void *arg) {
 usleep(600000);
}

int main() {
 pthread_t threadId;

 pthread_create(&threadId, NULL, myThread, NULL);
 pthread_join(threadId, NULL);

 return 0;
}