Programowanie systemowe – procesy i wątki
ćwiczenia laboratoryjne
Przydatne moduły i metody
-
os
-
os.fork
- tworzy proces. wartości zwracane
-
-1
– jeżeli wystąpił błąd (nie udało się utworzyć procesu)
-
0
– jeżeli proces został utworzony (stał się dzieckiem procesu nadrzędnego)
-
PID
procesu potomnego (większy niż 0
)
– jeżeli proces utworzył proces potomny
-
os.getpid
- zwraca identyfikator bieżącego procesu
-
os.getppid
- zwraca identyfikator nadrzędnego procesu
-
os.wait
- czeka na zakończenie lub zatrzymanie procesów potomnych
-
os.waitpid
- czeka na zakończenie lub zatrzymanie procesu potomnego
-
os.kill
- wysyła sygnał do procesu o podanym PID
-
signal
-
threading
-
sys
-
time
-
time.sleep
- zawiesza wykonanie procesu na pewien czas (sekundy)
Zadania
Zadanie 1.
Przed uruchomieniem postaraj się odgadnąć co wyświetli program w Python:
import os
print("pierwszy napis")
pid = os.fork()
if pid > 0: os.wait()
print("drugi napis")
pid = os.fork()
if pid > 0: os.wait()
print("trzeci napis")
Następnie skompiluj, uruchom oraz sprawdź, co zostanie wyświetlone. Uzasadnij działanie tego programu
oraz sprawdź co się stanie jeśli usuniesz
if pid > 0: os.wait()
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ł:
import sys
import signal
def handleSignal(s):
sys.stdout.write("HELLO")
signal.signal(signal.SIGINT, handleSignal)
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ć metody:
random.randint
.
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ć metody:
random.randint
.
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:
products = ["Mleko", "Chleb", "Masło", "Ser", "Jabłka", "Banany", "Czekolada", "Kawa", "Herbata", "Cukier"]
Otwarcie potoku nazwanego:
open
.
Wysyłanie, odebranie wiadomości i zamknięcie do/z potoku nazwanego:
obiekt.write(tekst)
,
obiekt.readline()
,
obiekt.close()
.
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ć metody:
random.randint
.
Podpowiedź 2: Przykładowy program tworzący wątek:
import threading
import time
def myThread():
time.sleep(60)
thread = threading.Thread(target=myThread)
thread.start()
thread.join()