Sobes.tech
Junior

Co je to paralelismus v programování?

sobes.tech AI

Odpověď od AI

Paralelismus v programování je provádění několika úkolů současně nebo zdánlivě současně, což umožňuje zvýšit výkon a odezvu aplikací.

Rozlišují se různé druhy paralelismu:

  • Multiprocessing (víceprocesorovost): Používá několik nezávislých procesů, každý se svým vlastním adresním prostorem. Tím obchází omezení GIL (Global Interpreter Lock) v CPythonu a je vhodný pro CPU-intenzivní úlohy.

    import multiprocessing
    import time
    
    def worker(num):
        """Nějaká práce"""
        time.sleep(1)
        print(f'Worker {num} dokončil')
    
    if __name__ == '__main__':
        processes = []
        for i in range(5):
            p = multiprocessing.Process(target=worker, args=(i,))
            processes.append(p)
            p.start()
    
        for p in processes:
            p.join()
        print("Všichni pracovníci dokončili")
    
  • Multithreading (vícevláknové zpracování): Používá několik vláken v rámci jednoho procesu, sdílejících společný adresní prostor. Kvůli GIL v CPythonu se vlákna nespouštějí paralelně na různých jádrech pro CPU-bound úlohy, ale jsou efektivní pro I/O-bound úlohy.

    import threading
    import time
    
    def worker(num):
        """Nějaká práce"""
        time.sleep(1) # Simulace I/O operace
        print(f'Vlakno {num} dokončilo')
    
    vlákna = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(i,))
        vlákna.append(t)
        t.start()
    
    for t in vlákna:
        t.join()
    print("Všechna vlákna dokončena")
    
  • Asynchronní programování (Asyncio): Používá jedno vlákno a smyčku událostí (event loop) pro správu úloh. Vhodné pro vysoce zatížené I/O-bound aplikace a webové servery. Neblokuje provádění při čekání na I/O.

    import asyncio
    import time
    
    async def worker(num):
        """Nějaká asynchronní práce"""
        await asyncio.sleep(1) # Asynchronní čekání na I/O
        print(f'Async worker {num} dokončil')
    
    async def main():
        úlohy = []
        for i in range(5):
            úloha = asyncio.create_task(worker(i))
            úlohy.append(úloha)
        await asyncio.gather(*úlohy)
        print("Všichni asynchronní pracovníci dokončili")
    
    if __name__ == '__main__':
        asyncio.run(main())
    

Výběr přístupu závisí na charakteru úkolu:

Přístup CPU-bound úkoly I/O-bound úkoly GIL Použití paměti
Víceprocesorovost Výborně Dobře Obchází Velké (svůj proces)
Vícevláknové zpracování Špatně (kvůli GIL) Výborně Blokuje Malé (sdílený proces)
Asynchronní Špatně Výborně Neblokuje Malé (jeden vlákno)

Paralelismus vyžaduje opatrné řízení synchronizace a zdrojů, aby se předešlo závodním podmínkám (race conditions) a deadlockům.