- 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 เดิม การจัดการข้อผิดพลาด และการทดสอบ ดังนั้นจึงควรตรวจสอบและเตรียมความพร้อมให้เพียงพอ
ยังไม่มีความคิดเห็น