การเขียนโปรแกรมแบบอะซิงโครนัสใน Python

Mar 06 2023
การเขียนโปรแกรมแบบอะซิงโครนัสเป็นกระบวนทัศน์การเขียนโปรแกรมที่ช่วยให้กระบวนการจำนวนมากดำเนินการพร้อมกันและเป็นอิสระต่อกัน โดยไม่ต้องรอให้กระบวนการหนึ่งเสร็จสิ้นก่อนที่จะดำเนินการต่อไป ในบล็อกโพสต์นี้ เราจะมาดูกันว่าการเขียนโปรแกรมอะซิงโครนัสแบบใดและวิธีใช้งานในไพธอน
การเขียนโปรแกรมแบบอะซิงโครนัสใน Python

การเขียนโปรแกรมแบบอะซิงโครนัสเป็นกระบวนทัศน์การเขียนโปรแกรมที่ช่วยให้กระบวนการจำนวนมากดำเนินการพร้อมกันและเป็นอิสระต่อกันโดยไม่ต้องรอให้กระบวนการหนึ่งเสร็จสิ้นก่อนที่จะดำเนินการต่อไป ในบล็อกโพสต์นี้ เราจะมาดูกันว่าการเขียนโปรแกรมอะซิงโครนัสแบบใดและวิธีใช้งานในไพธอน

การเขียนโปรแกรมแบบอะซิงโครนัสคืออะไร?

ในการเขียนโปรแกรมแบบซิงโครนัส คอมพิวเตอร์จะดำเนินการตามคำสั่งตามลำดับ โดยปิดกั้นการดำเนินการจนกว่างานจะเสร็จสิ้นก่อนที่จะดำเนินการต่อไป
ในทางกลับกัน การเขียนโปรแกรมแบบอะซิงโครนัสทำให้โปรแกรมสามารถเริ่มการทำงานหนึ่งแล้วดำเนินการต่อโดยไม่หยุดดำเนินการจนกว่างานดั้งเดิมจะเสร็จสิ้น

การเขียนโปรแกรมแบบอะซิงโครนัสมีประโยชน์อย่างยิ่งในสถานการณ์ที่กระบวนการ เช่น เครือข่าย I/O หรือการดำเนินการฐานข้อมูล อาจใช้เวลานานกว่าจะเสร็จสมบูรณ์ การเขียนโปรแกรมแบบอะซิงโครนัสสามารถช่วยเพิ่มประสิทธิภาพและการตอบสนองในแอปพลิเคชันซอฟต์แวร์โดยอนุญาตให้โปรแกรมดำเนินกิจกรรมอื่นต่อไปในขณะที่รอให้การทำงานที่ช้าเสร็จสิ้น

ขึ้นอยู่กับภาษาการเขียนโปรแกรมและเฟรมเวิร์กที่ใช้ การเขียนโปรแกรมแบบอะซิงโครนัสสามารถทำได้โดยใช้กลยุทธ์ต่างๆ เช่น การเรียกกลับ สัญญา หรือคีย์เวิร์ด async/await

ความแตกต่างระหว่างการเขียนโปรแกรมแบบอะซิงโครนัสและการประมวลผลหลายส่วน

ความแตกต่างที่สำคัญระหว่างการเขียนโปรแกรมแบบอะซิงโครนัสและการประมวลผลหลายตัวคือ การเขียนโปรแกรมแบบอะซิงโครนัสช่วยให้การดำเนินการแบบไม่ปิดกั้นเกิดขึ้นภายในเธรดเดียว ในขณะที่การประมวลผลหลายตัวใช้ คอร์ หรือกระบวนการจำนวนมากในการทำงานให้เสร็จพร้อมกัน

ความแตกต่างระหว่างการเขียนโปรแกรมแบบอะซิงโครนัสและเธรด

ความแตกต่างที่สำคัญระหว่างการเขียนโปรแกรมแบบอะซิงโครนัสและเธรดคือ การเขียนโปรแกรมแบบอะซิงโค รนัส ช่วยให้สามารถดำเนินการแบบไม่บล็อกได้โดยใช้เธรดเดียว ในขณะที่เธรดใช้หลายเธรดเพื่อทำงานหลายอย่างพร้อมกัน

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่าง: Treading vs Multiprocessing vs Asynchronous Programming

วิธีการใช้ Asyncio ?

ก่อนอื่นมาสร้างโปรแกรมง่ายๆ ที่เริ่มทำงานทีละอย่างและทำงานให้เสร็จ

import time
import asyncio

def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    for job in todo:
        do_job(job)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

main()

# OUTPUT
# Job A started
# Job Adone
# Job B started
# Job B done
# Job C started
# Job C done
# Took: 3.009 seconds

การสร้างและเรียกใช้ Coroutines

Coroutine เป็นฟังก์ชันประเภทหนึ่งที่สามารถถูกขัดจังหวะและกลับมาทำงานต่อได้หลายครั้งตลอดการดำเนินการ กล่าวอีกนัยหนึ่ง โครูทีนอนุญาตให้คุณเขียนโค้ดที่สามารถถูกขัดจังหวะ ทำอย่างอื่น แล้วกลับมาทำงานต่อจากจุดที่ค้างไว้

สำหรับการสร้างcoroutinesเราจำเป็นต้องใช้asyncคำหลักก่อนdefคำหลัก การเรียกคอร์รูทีนไม่ได้เรียกฟังก์ชันที่เราต้องการเรียกใช้ มันสร้างงาน

import time
import asyncio

async def do_job(s):
  ...

async def main():
  ...

main()

asyncio.run(main())

หากคุณเรียกใช้รหัสนี้ คุณอาจได้รับข้อผิดพลาดดังนี้:

RuntimeWarning: coroutine '...' was never awaited

import time
import asyncio

async def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

async def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    for job in todo:
        await do_job(job)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

asyncio.run(main())

# OUTPUT
# Job A started
# Job A done
# Job B started
# Job B done
# Job C started
# Job C done
# Took: 3.009 seconds

await asyncio.sleep(1)

tasks = [asyncio.create_task(do_job(item)) for item in todo]
done, pending = await asyncio.wait(tasks)

import time
import asyncio

async def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

async def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    
    tasks = [asyncio.create_task(do_job(item)) for item in todo]
    done, pending = await asyncio.wait(tasks)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

asyncio.run(main())

# OUTPUT
# Job A started
# Job B started
# Job C started
# Job A done
# Job B done
# Job C done
# Took: 1.009 seconds

คุณสามารถดูวิดีโอเพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับการเขียนโปรแกรมแบบอะซิงโครนัสในไพทอน ( ข้อมูลเบื้องต้นเกี่ยวกับ async Python | การเขียนโปรแกรมรวบรวมข้อมูลเว็บ )