Sobes.tech
Junior

Čo je paralelizmus v programovaní?

sobes.tech AI

Odpoveď od AI

Paralelizmus v programovaní je vykonávanie viacerých úloh súčasne alebo zdanie súčasnosti, čo umožňuje zvýšiť výkon a odozvu aplikácií.

Rozlišujú sa rôzne druhy paralelizmu:

  • Multiprocessing (viacprocesorovosť): Používa niekoľko nezávislých procesov, každý so svojím adresným priestorom. Tým obchádza obmedzenie GIL (Global Interpreter Lock) v CPython a je vhodný pre CPU-intenzívne úlohy.

    import multiprocessing
    import time
    
    def worker(num):
        """Nejaká práca"""
        time.sleep(1)
        print(f'Pracovník {num} dokončil')
    
    if __name__ == '__main__':
        procesy = []
        for i in range(5):
            p = multiprocessing.Process(target=worker, args=(i,))
            procesy.append(p)
            p.start()
    
        for p in procesy:
            p.join()
        print("Všetci pracovníci dokončili")
    
  • Multithreading (viacvláknové spracovanie): Používa niekoľko vlákien v rámci jedného procesu, ktoré zdieľajú spoločný adresný priestor. Kvôli GIL v CPython sa vlákna nespúšťajú paralelne na rôznych jadrách pre CPU-bound úlohy, ale sú efektívne pre I/O-bound úlohy.

    import threading
    import time
    
    def worker(num):
        """Nejaká práca"""
        time.sleep(1) # Simulácia I/O operácie
        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šetky vlákna dokončili")
    
  • Asynchrónne programovanie (Asyncio): Používa jedno vlákno a slučku udalostí (event loop) na správu úloh. Vhodné pre vysoko zaťažené I/O-bound aplikácie a webové servery. Neblokuje vykonávanie pri čakaní na I/O.

    import asyncio
    import time
    
    async def worker(num):
        """Nejaká asynchrónna práca"""
        await asyncio.sleep(1) # Asynchrónne čakanie 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šetci asynchrónni pracovníci dokončili")
    
    if __name__ == '__main__':
        asyncio.run(main())
    

Výber prístupu závisí od charakteru úlohy:

Prístup CPU-bound úlohy I/O-bound úlohy GIL Použitie pamäte
Mnohoprocesorové Výborne Dobre Obchádza Veľké (svoj proces)
Viacvláknové Zle (kvôli GIL) Výborne Blokuje Malé (spoločný proces)
Asynchrónne Zle Výborne Neblokuje Malé (jeden vlákno)

Paralelizmus vyžaduje opatrné riadenie synchronizácie a zdrojov, aby sa predišlo podmienkam súťaže (race conditions) a mŕtvym bodom (deadlocks).