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): იყენებს რამდენიმე ძაფს ერთ პროცესში, რომლებიც იყოფიან საერთო მისამართის სივრცეს. CPython-ში GIL-ის გამო, ძაფები არ მუშაობენ პარალელურად CPU-ს ბადეზე, მაგრამ ეფექტურია I/O-სა და სხვა ბადეზე დამოკიდებულ დავალებებზე.

    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-სა და ვებ სერვერებისთვის. არ ბლოკავს შესრულებას 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).