Sobes.tech
Junior

Kas yra paralelizmas programavime?

sobes.tech AI

Atsakymas iš AI

Lygiagretumas programavime yra kelių užduočių vykdymas vienu metu arba vaizduojamas kaip vienu metu, leidžiantis pagerinti programų našumą ir reagavimo greitį.

Yra keli lygiagretumo tipai:

  • Daugiaprocesorystė (Multiprocessing): Naudoja kelis nepriklausomus procesus, kiekvienas su savo adresų erdve. Tai apeina GIL (Global Interpreter Lock) apribojimą CPython ir tinka CPU intensyvioms užduotims.

    import multiprocessing
    import time
    
    def worker(num):
        """Tam tikras darbas"""
        time.sleep(1)
        print(f'Darbininkas {num} baigė')
    
    if __name__ == '__main__':
        procesai = []
        for i in range(5):
            p = multiprocessing.Process(target=worker, args=(i,))
            procesai.append(p)
            p.start()
    
        for p in procesai:
            p.join()
        print("Visi darbininkai baigė")
    
  • Daugiasluoksnė (Multithreading): Naudoja kelis gijas viename procese, kurios dalijasi bendrą adresų erdvę. Dėl GIL CPython, gijos nevyksta lygiagrečiai keliuose branduoliuose CPU-bound užduotims, bet yra efektyvios I/O-bound užduotims.

    import threading
    import time
    
    def worker(num):
        """Tam tikras darbas"""
        time.sleep(1) # I/O operacijos imitacija
        print(f'Gija {num} baigė')
    
    gijos = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(i,))
        gijos.append(t)
        t.start()
    
    for t in gijos:
        t.join()
    print("Visos gijos baigėsi")
    
  • Asinchroninis programavimas (Asyncio): Naudoja vieną giją ir įvykių ciklą (event loop) užduočių valdymui. Tinka didelės apkrovos I/O-bound programoms ir interneto serveriams. Neužblokuoja vykdymo laukiant I/O.

    import asyncio
    import time
    
    async def worker(num):
        """Tam tikras asinchroninis darbas"""
        await asyncio.sleep(1) # Asinchroninis laukimas I/O
        print(f'Async worker {num} baigė')
    
    async def main():
        užduotys = []
        for i in range(5):
            užduotis = asyncio.create_task(worker(i))
            užduotys.append(užduotis)
        await asyncio.gather(*užduotys)
        print("Visi asinchroniniai darbuotojai baigė")
    
    if __name__ == '__main__':
        asyncio.run(main())
    

Pasirinkimas priklauso nuo užduoties pobūdžio:

Požiūris CPU-kontūruotos užduotys I/O-kontūruotos užduotys GIL Atminties naudojimas
Daugiaprocesorinis Puikus Geras Apima Didelis (savo procesas)
Daugiasluoksnis Blogas (dėl GIL) Puikus Blokuoja Mažas (bendras procesas)
Asinchroninis Blogas Puikus Neblokuoja Mažas (vienas gijas)

Lygiagretumas reikalauja atsargiai valdyti sinchronizaciją ir išteklius, kad būtų išvengta lenktynių sąlygų (race conditions) ir mirties taškų (deadlocks).