6. cvičení - Bariéry
Barrier Object
Tato třída je jednoduché synchronizační primitivum, které používá fixní počet vláken, která na sebe musí
po dokončení výpočtu počkat jedno na druhé. Každé vlákno použije metodu wait()
pro průchod bariérou.
Vlákna jsou blokována dokud všechna vlákna nezavolají wait()
. Jakmile čekají na bariéře všechna vlákna,
tak jsou současně puštěna. Bariéra může využívána opakovaně pro stejný počet vláken.
import threading
from random import randint
import time
# Thread-safe tisk textu na obrazovku
class Printer:
_mutex = threading.Semaphore(value=1)
@classmethod
def print_text(self, text: str):
with self._mutex:
print(text)
# Vytvoříme bariéru pro 6 vláken (Main + 5 pomocí threading.Thread)
barrier = threading.Barrier(6)
def run(id):
global barrier
time.sleep(randint(0, 5))
Printer.print_text("Thread {} reached the barrier.".format(id))
# Čekání na bariéře
barrier.wait()
for id in range(5):
t = threading.Thread(target=run, args=(id,))
t.start()
Printer.print_text("Main thread reached the barrier.")
barrier.wait()
Printer.print_text("All threads were released from the barrier.")
Úkoly
Máme pole nesetřízených čísel numbers
o velikosti n, kde n je sudé.
Vytvořte n vláken, kde každé vlákno spustí funkci sort(id)
, kde id
je id
vlákna v rozsahu range(n)
. Ve funkci sort provedeme sérii kol, tak že
v sudá kola budou vlákna se sudým id porovnávat hodnoty numbers[id]
a numbers[id + 1]
a
pokud jsou tyto hodnoty nesetřízené, tak provedeme jejich prohození. Stejnou operaci provedem v lichých kolech
pro vlákna s lichým id
. Vlakno s id == n - 1
nedělá v lichá kola nic.
numbers = [2, 4, 5, 6, 3, 10, 99, 18]
def sort(id):
# Zde vložte Vaše řešení.
threads = [threading.Thread(target=sort, args=(id,)) for id in range(len(numbers))]
for t in threads:
t.start()
for t in threads:
t.join()
(Bodovaný) Upravte první úkol tak, aby program skončil hned jak bude pole setřízeno.