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)