• Asyncio เป็นวิธีที่ดีในการจัดการโปรแกรมแบบ I/O-bound ใน Python และโดยพื้นฐานแล้วเป็นเลเยอร์ที่ดีที่สร้างอยู่บน Python Generator
  • Generator ช่วยให้โค้ดใช้หน่วยความจำอย่างมีประสิทธิภาพ และสามารถหยุดและทำงานต่อของฟังก์ชันได้ด้วยคีย์เวิร์ด yield
  • การใช้ yield from ทำให้ generator สามารถเรียก sub-generator หรืออ็อบเจ็กต์ iterable ได้ จึงสามารถสร้าง generator chain ได้

อีเวนต์ลูป

  • หัวใจของ Asyncio คือ event loop ที่ทำหน้าที่รันและจัดการ task ปัจจุบัน
  • Event loop จะวนลูปผ่านรายการ task และรันแต่ละ task ด้วย next(task)
  • Task จะใช้ yield เพื่อหยุดการทำงานชั่วคราวระหว่างงาน I/O และส่งสิทธิ์ควบคุมกลับไปยัง event loop

การพักรอ

  • สามารถเพิ่ม sub-generator ให้กับ task ได้ด้วย yield from
  • เมื่อเพิ่ม sleep generator ก็จะสามารถหยุดการทำงานของ task ไว้จนกว่าจะถึงเวลาที่กำหนด
  • เมื่อ Sleep ออกจากลูป while จะเกิดข้อยกเว้น StopIteration ทำให้ yield from ในฟังก์ชัน task ดำเนินต่อไปยังบรรทัดถัดไปของโค้ด

จาก Yield สู่ Await

  • สามารถเปลี่ยนจาก yield ไปเป็น await ได้ด้วยเมธอดดันเดอร์ __await__ และคีย์เวิร์ด async
  • คีย์เวิร์ด await สามารถใช้เรียกเมธอด __await__ ของอินสแตนซ์คลาส หรือใช้กับคอร์รูทีน (อ็อบเจ็กต์ที่สร้างจากฟังก์ชัน async) ได้
  • คีย์เวิร์ด await มองได้ว่าเป็นคำพ้องความหมายของ yield from โดยมีการตรวจสอบความถูกต้องเพิ่มเติมเล็กน้อย
  • สามารถสร้างคลาส Task ของตัวเองและ implement เมธอด __await__ แล้วเพิ่ม task ที่สร้างด้วยฟังก์ชัน create_task เข้าไปใน event loop
  • ตัวจัดการ event loop จะรัน task และเมื่อเกิดข้อยกเว้น StopIteration ก็จะถือว่า task นั้นเสร็จสิ้น
  • ฟังก์ชัน Sleep ก็ต้องปรับให้รองรับ async ด้วยเช่นกัน

AsyncIO และ Await

  • ในโค้ดข้างต้น หากเปลี่ยน "jacobio" เป็น "asyncio" ก็จะกลายเป็นการใช้แพ็กเกจ asyncio อย่างเต็มรูปแบบ
  • Asyncio ทำงานได้มากกว่านี้อีกมาก แต่เราสามารถจำลองแกนหลักของ asyncio ขึ้นมาใหม่ตั้งแต่พื้นฐานของ generator ได้
  • ในแพ็กเกจ asyncio จริง ยังมีฟังก์ชันอย่าง asyncio.gather() สำหรับจัดการหลาย task ได้ด้วย

ความเห็นของ GN⁺

  • บทความนี้อธิบายหลักการทำงานของ asyncio ด้วย generator ได้อย่างเข้าใจง่าย จึงน่าจะช่วยนักพัฒนาที่เพิ่งเริ่มต้นกับ asyncio ได้มาก
  • Asyncio เป็นไลบรารีที่เหมาะกับการประมวลผล I/O ประสิทธิภาพสูง และหากเข้าใจโครงสร้างภายในผ่านบทความนี้ ก็น่าจะนำไปใช้ในโปรเจ็กต์จริงได้อย่างมีประสิทธิภาพมากขึ้น
  • อย่างไรก็ตาม asyncio จริงมีโครงสร้างที่ซับซ้อนกว่านี้มาก ดังนั้นหากจะใช้งานในงานจริง ก็ควรศึกษาเชิงลึกเพิ่มเติมจากเอกสารทางการและแหล่งข้อมูลอื่น ๆ
  • ไลบรารีอื่นที่ให้ความสามารถคล้าย Asyncio ก็มีอย่าง Trio และ Curio ซึ่งการลองเปรียบเทียบความแตกต่างกับเครื่องมือเหล่านี้ก็น่าสนใจเช่นกัน
  • เมื่อต้องการนำ Asyncio ไปใช้ ยังมีเรื่องที่ต้องพิจารณาอีกมาก เช่น ความเข้ากันได้กับโค้ดแบบ synchronous เดิม การจัดการข้อผิดพลาด และการทดสอบ ดังนั้นจึงควรตรวจสอบและเตรียมความพร้อมให้เพียงพอ

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น