Sobes.tech
Junior

Какво е паралелизъм в програмирането?

sobes.tech AI

Отговор от AI

Паралелизмът в програмирането е изпълнение на няколко задачи едновременно или илюзията за едновременност, което позволява да се увеличи производителността и отзивчивостта на приложенията.

Различават се няколко вида паралелизъм:

  • Многопроцесност (Multiprocessing): Използва няколко независими процеса, всеки със собствено адресно пространство. Това преодолява ограниченията на GIL (Global Interpreter Lock) в CPython и е подходящо за CPU-интензивни задачи.

    import multiprocessing
    import time
    
    def worker(num):
        """Някаква работа"""
        time.sleep(1)
        print(f'Работник {num} приключи')
    
    if __name__ == '__main__':
        процеси = []
        for i in range(5):
            p = multiprocessing.Process(target=worker, args=(i,))
            процеси.append(p)
            p.start()
    
        for p in процеси:
            p.join()
        print("Всички работници приключиха")
    
  • Многопоточност (Multithreading): Използва няколко нишки в рамките на един процес, които споделят общо адресно пространство. Поради GIL в CPython, нишките не се изпълняват паралелно на различни ядра за CPU-bound задачи, но са ефективни за I/O-bound задачи.

    import threading
    import time
    
    def worker(num):
        """Някаква работа"""
        time.sleep(1) # Имитира I/O операция
        print(f'Нишка {num} приключи')
    
    нишки = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(i,))
        нишки.append(t)
        t.start()
    
    for t in нишки:
        t.join()
    print("Всички нишки приключиха")
    
  • Асинхронно програмиране (Asyncio): Използва една нишка и цикъл на събития (event loop) за управление на задачите. Подходящо за натоварени I/O-bound приложения и уеб сървъри. Не блокира изпълнението при изчакване на I/O.

    import asyncio
    import time
    
    async def worker(num):
        """Някаква асинхронна работа"""
        await asyncio.sleep(1) # Асинхронно изчакване на I/O
        print(f'Async worker {num} приключи')
    
    async def main():
        задачи = []
        for i in range(5):
            задача = asyncio.create_task(worker(i))
            задачи.append(задача)
        await asyncio.gather(*задачи)
        print("Всички асинхронни работници приключиха")
    
    if __name__ == '__main__':
        asyncio.run(main())
    

Изборът на подход зависи от характера на задачата:

Подход CPU-зависими задачи I/O-зависими задачи GIL Използване на памет
Многопроцесорност Отлично Добре Обхваща Голямо (свой процес)
Многопоточност Лошо (заради GIL) Отлично Блокира Малко (общ процес)
Асинхронност Лошо Отлично Не блокира Малко (един поток)

Паралелизмът изисква внимателно управление на синхронизацията и ресурсите, за да се избегнат състезателни условия (race conditions) и взаимни блокировки (deadlocks).