9. cvičení - Synchronizovaný vektor
Lamda výrazy a funkce map
Lambda výraz slouží k definici anonymní funkce a tato funkce může mít pouze jeden řádek.
# Lambda výraz který sečte čísla x a y
f = lambda x, y: x + y
f(10, 20) # -> 30
# Můžeme vytvořit i lambda výraz bez argumentu
f = lambda: 10
f() # -> 10
Funkce map bere 2 argumenty a to funkci a sekvenci. Výsledkem je nová sekvence, kde je funkce aplikována všechny prvky v původní sekvenci.
numbers = [1,2,3,4,5,6,7,8,9]
# Funkce map vrací iterátor a tedy jej musíme převést na list
list(map(lambda x: x * x, numbers)) # -> [1, 4, 9, 16, 25, 36, 49, 64, 81]
Úkoly
Naprogramujte synchronizovaný vektor fixní délky, kde bude možné nastavovat a číst různé složky současně z různých vláken. Například vlákno 1 bude nastavovat první složku a současně bude vlákno 2 číst třetí složku toho samého vektoru.
from random import randint
VECTOR_SIZE = 10
# Vytvoří nulový vektor délky 10
vector = SyncVector(VECTOR_SIZE)
# Vytvoří vektor délky 10, kde všechny složky mají hodnotu 1
vector = SyncVector(VECTOR_SIZE, initial_value=1)
# Vytvoří náhodný vektor délky 10
random_vector = SyncVector(VECTOR_SIZE, lambda: initial_func=randint(0, 100))
# Získání i-té složky vektoru
vector.get(index)
# Nastavení i-té složky vektoru
vector.set(value, index)
(Bodovaný) Naprogramujte funkci nmapv
, která se chová jako map
, ale používá k
výpočtu k
vláken a nevytváří nový vektor, ale mění hodnoty původního. Jako první argument bere mapovací funkci.
Jako druhý vektor z předchozího úkolu a třetí argument je nepovinný a udává počet vláken použitých k výpočtu.
Výchozí hodnotu nastavte podle vlastního uvážení. V rámci testů zkuste vymyslet náročnějsí mapovací funkci
a ověřte, jak počet vláken ovlivňuje čas výpočtu.
from random import randint
vector = SyncVector(100, lambda: randint(0, 100))
# Mapujeme 2. mocninu na vector a použijeme 10 vláken.
nmapv(lambda e: e * e, vector, 10)