เรื่องเล่าจากโลก Async: ทำไม "Asynchrony ไม่ใช่ Concurrency"

เรามักจะได้ยินว่า “Concurrency ≠ Parallelism” แต่ผู้เขียนเสนอว่า มีสิ่งที่ “ขาดหายไปจากนิยาม” คือ Asynchrony และการละเลยความแตกต่างนี้ ส่งผลเสียต่อโลกการเขียนโปรแกรม เช่น การต้องสร้างไลบรารีแยกระหว่าง synchronous และ asynchronous โดยไม่จำเป็น

คำจำกัดความใหม่ที่บทความเสนอ
Asynchrony คือความเป็นไปได้ที่ task จะทำงาน “นอกลำดับ” ได้โดยไม่ผิด
เช่น การเซฟไฟล์ A และ B ไม่ต้องรอหรือสลับกันก็ได้ หากผลลัพธ์สุดท้ายถูกต้อง

Concurrency คือความสามารถในการ “ทำงานหลายอย่างพร้อมกัน”
จะเป็นแบบ task switching หรือหลาย thread ก็ได้

Parallelism คือ “การรันหลาย task ทางกายภาพพร้อมกันจริง ๆ”
ใช้ CPU หลายตัว หรือหลาย core ในเวลาเดียวกัน

ตัวอย่างที่ใช้ช่วยให้เข้าใจ Asynchrony vs Concurrency ได้ดี
เช่นเซฟไฟล์ที่ลำดับไม่สำคัญ = asynchronous แต่ client-server ต้อง concurrent

Zig แสดงให้เห็นว่า async ไม่ได้หมายถึง concurrent เสมอ
io.async ใน Zig สามารถรันแบบ single-threaded ได้โดยไม่ deadlock ถ้าไม่มีความต้องการ concurrency

Zig มี primitive แยกสำหรับ async ที่ต้อง concurrent คือ io.asyncConcurrent
ช่วยให้โค้ด “แสดงเจตนา” ชัดเจนว่าการทำงานต้องพร้อมกันเพื่อให้ถูกต้อง

Green threads ทำงานโดยการ “yield” (สลับ stack memory)
ช่วยให้ synchronous code ทำงานร่วมกับ concurrency โดยไม่ต้องใช้ async/await keyword เลย

การแยก async กับ concurrency ช่วยลดการแพร่ async แบบ viral
ไม่ต้องให้ผู้ใช้หรือไลบรารีถูกบังคับเขียน async ทั้งหมดจาก dependency เดียว

โค้ด synchronous ยังสามารถรันได้พร้อมกัน ถ้า wrapper รอบ ๆ เป็น asynchronous
ทำให้ ecosystem ไม่ต้องแยก async กับ sync libraries

การใช้ async โดยไม่เข้าใจความต้องการ concurrency อาจทำให้โค้ดผิดพลาด
เช่น server.accept กับ client.connect ต้อง concurrency ไม่ใช่แค่ async ธรรมดา

การใช้ async แบบ “viral” ส่งผลเสียต่อ ecosystem ไลบรารี
เช่นต้องสร้าง redis-py กับ asyncio-redis แยกกัน โดยไม่มีความจำเป็นจริง

ไม่ใช้ yield หรือ task switching primitives ทำให้ async ไม่สามารถรัน concurrent ได้
เพราะ async “เป็นแค่ลำดับรันแบบไม่เรียง” ไม่ใช่ระบบรันหลายงานพร้อมกัน

ระบบที่บังคับใช้ stackless coroutine + async/await อาจสร้าง deadlock หากไม่ได้ออกแบบดี
โดยเฉพาะถ้าระบบไม่มีการแสดงเจตนาในโค้ดว่าต้อง concurrent

https://kristoff.it/blog/asynchrony-is-not-concurrency/
🎙️ เรื่องเล่าจากโลก Async: ทำไม "Asynchrony ไม่ใช่ Concurrency" เรามักจะได้ยินว่า “Concurrency ≠ Parallelism” แต่ผู้เขียนเสนอว่า มีสิ่งที่ “ขาดหายไปจากนิยาม” คือ Asynchrony และการละเลยความแตกต่างนี้ ส่งผลเสียต่อโลกการเขียนโปรแกรม เช่น การต้องสร้างไลบรารีแยกระหว่าง synchronous และ asynchronous โดยไม่จำเป็น 💡 คำจำกัดความใหม่ที่บทความเสนอ ✅ Asynchrony คือความเป็นไปได้ที่ task จะทำงาน “นอกลำดับ” ได้โดยไม่ผิด ➡️ เช่น การเซฟไฟล์ A และ B ไม่ต้องรอหรือสลับกันก็ได้ หากผลลัพธ์สุดท้ายถูกต้อง ✅ Concurrency คือความสามารถในการ “ทำงานหลายอย่างพร้อมกัน” ➡️ จะเป็นแบบ task switching หรือหลาย thread ก็ได้ ✅ Parallelism คือ “การรันหลาย task ทางกายภาพพร้อมกันจริง ๆ” ➡️ ใช้ CPU หลายตัว หรือหลาย core ในเวลาเดียวกัน ✅ ตัวอย่างที่ใช้ช่วยให้เข้าใจ Asynchrony vs Concurrency ได้ดี ➡️ เช่นเซฟไฟล์ที่ลำดับไม่สำคัญ = asynchronous แต่ client-server ต้อง concurrent ✅ Zig แสดงให้เห็นว่า async ไม่ได้หมายถึง concurrent เสมอ ➡️ io.async ใน Zig สามารถรันแบบ single-threaded ได้โดยไม่ deadlock ถ้าไม่มีความต้องการ concurrency ✅ Zig มี primitive แยกสำหรับ async ที่ต้อง concurrent คือ io.asyncConcurrent ➡️ ช่วยให้โค้ด “แสดงเจตนา” ชัดเจนว่าการทำงานต้องพร้อมกันเพื่อให้ถูกต้อง ✅ Green threads ทำงานโดยการ “yield” (สลับ stack memory) ➡️ ช่วยให้ synchronous code ทำงานร่วมกับ concurrency โดยไม่ต้องใช้ async/await keyword เลย ✅ การแยก async กับ concurrency ช่วยลดการแพร่ async แบบ viral ➡️ ไม่ต้องให้ผู้ใช้หรือไลบรารีถูกบังคับเขียน async ทั้งหมดจาก dependency เดียว ✅ โค้ด synchronous ยังสามารถรันได้พร้อมกัน ถ้า wrapper รอบ ๆ เป็น asynchronous ➡️ ทำให้ ecosystem ไม่ต้องแยก async กับ sync libraries ‼️ การใช้ async โดยไม่เข้าใจความต้องการ concurrency อาจทำให้โค้ดผิดพลาด ⛔ เช่น server.accept กับ client.connect ต้อง concurrency ไม่ใช่แค่ async ธรรมดา ‼️ การใช้ async แบบ “viral” ส่งผลเสียต่อ ecosystem ไลบรารี ⛔ เช่นต้องสร้าง redis-py กับ asyncio-redis แยกกัน โดยไม่มีความจำเป็นจริง ‼️ ไม่ใช้ yield หรือ task switching primitives ทำให้ async ไม่สามารถรัน concurrent ได้ ⛔ เพราะ async “เป็นแค่ลำดับรันแบบไม่เรียง” ไม่ใช่ระบบรันหลายงานพร้อมกัน ‼️ ระบบที่บังคับใช้ stackless coroutine + async/await อาจสร้าง deadlock หากไม่ได้ออกแบบดี ⛔ โดยเฉพาะถ้าระบบไม่มีการแสดงเจตนาในโค้ดว่าต้อง concurrent https://kristoff.it/blog/asynchrony-is-not-concurrency/
KRISTOFF.IT
Asynchrony is not Concurrency
Yes I know about that one talk from Rob Pike.
0 ความคิดเห็น 0 การแบ่งปัน 70 มุมมอง 0 รีวิว