Race Condition ภัยคุกคามที่ Developer ทุกคนควรรู้

Sakul Montha
SCB TechX
Published in
2 min readDec 8, 2021

--

Race Condition สิ่งที่ Developer ทุกคนต้องรู้ เมื่อต้องทำงานกับ Multithread หรือกำลังเริ่มเข้าสู่วงการ at Scale ต้องบอกว่า Race Condition ไม่ใช่เรื่องใหม่ มันเกิดขึ้นมานานนับหลายสิบปีแล้ว “แต่มักจะพบกับคนที่ทำงานในระบบที่ค่อนข้างใหญ่ มี User ใช้ค่อนข้างมากในแต่ละวินาที…” นั่นจึงเป็นเหตุผลที่ว่า ทำไม Developer หลายคน ยังไม่รู้จัก เนื่องจากอาจจะยังไม่เคยเจอ Transaction ที่วิ่งเข้ามาพร้อมกัน จำนวนมาก

Race Condition

Race Condition เกิดขึ้นตอนไหนกันนะ

Race Condition มักพบได้ตอนที่เรามี Thread ตั้งแต่สองตัวขึ้นไป ซึ่งสามารถเข้าถึง (Access) และแก้ไขข้อมูลที่ใช้งานร่วมกันได้ (Shared data) (Mutable) ในเวลาเดียวกัน โดยที่คุณเองก็อาจจะไม่รู้ลำดับของ Thread ที่จะพยายามเข้าถึงข้อมูลที่คุณแชร์

ผลลัพธ์ของการเปลี่ยนแปลงข้อมูลจะขึ้นอยู่กับ Algorithm ของคุณว่าเป็นอย่างไร ตีความให้ง่ายกว่านั้นก็คือ Thread ทั้งสอง กำลังแข่ง (Race) เพื่อเข้าถึง หรือเปลี่ยนแปลงข้อมูลนั่นเอง

เรามักพบปัญหานี้ได้จาก (check-then-act) เพื่อให้เห็นภาพมากกว่านี้ ดู Code ดีกว่า

แล้วมันยังไงหละ… ก็บึ้มไงครับ สิ่งที่เกิดขึ้น ขึ้นอยู่กับ Algorithm ของคุณ Business Logic ของคุณเลย บางครั้งอาจจะทำให้ Order สินค้าผิดพลาด สั่งของ A ได้ของ C, Register X ได้ User Z อะไรแบบนี้เลย…

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

สำหรับท่านที่อยากรู้ว่าแล้วมัน Lock อย่างไรหละ ลองเอา Keyword สองคำนี้ไปหาดูได้ครับ Mutex กับ Semaphore

Variable access safe in shared-memory concurrency

เรามาดูกันว่า มันมีวิธีอะไรกันบ้างที่จะทำให้ Thread ของเรามัน Safe ลดโอกาสเกิด Race Condition…

Confinement

คือการที่เราจะไม่แชร์ ตัวแปรต่าง ๆ ระหว่าง Thread แล้วก็ Avoid global variables ด้วย

Immutability

เป็นอีกหนทางนึงที่จะมาช่วยเรา ซึ่งภาษาสมัยใหม่ ๆ ในปัจจุบันก็ให้ความสำคัญกับเรื่อง Immutable กันค่อนข้างมาก, ในกรณีที่ต้องการใช้ Immutable without Lock ก็จะต้องมาดูเรื่อง no mutator methods, ทุกฟิลด์เป็น private และ final, no representation exposure และ no mutation whatsoever of mutable objects in the rep — not even beneficent mutation

Threadsafe data types

หา Data types ที่เป็น Threadsafe มาครับ กำปั้นทุบดินมาก ฮ่า ๆ จริง ๆ คือให้เรา Encapsulate data ที่ต้องการแชร์ใน Threadsafe data types ต้องบอกว่า รู้ไว้จะได้เลือกใช้ Data types ถูกแหละ ถ้าอย่างใน Java ก็เช่น StringBuffer อย่าง Iterators นี่ก็ไม่ปลอดภัยนะครับ

ถ้าสนใจเรื่องนี้จริง ๆ แนะนำให้อ่าน Wrapper Collections และ Concurrent Collections ต่อครับ

Synchronization

ใช้การ Synchonization เพื่อป้องกันไม่ให้ Thread เข้าถึงตัวแปรพร้อมกัน การ Synchonization คือสิ่งที่คุณต้องสร้าง Data types ที่เป็น Thread safe ของคุณเอง

Conclusion

Race Condition ไม่ใช่เรื่องไกลตัวเลยครับ รู้ไว้ก็ดี ตอนนี้อาจจะยังไม่ได้ใช้ แต่อนาคตอาจจะได้ใช้แน่ ๆ ครับ ส่วนสำหรับคนที่ทำงาน at Scale อยู่แล้ว เชื่อว่ายังไงก็ต้องเคยประสบพบเจอกันมาบ้างอยู่แล้ว ก็หวังว่าจะได้รำลึก หรือไม่ก็ได้ Methodology บางอันเพิ่มไปนะครับ

อีกอย่างนึงที่ต้องบอกคือ Race Condition ไม่ได้มีแค่ในเฉพาะ Programming เท่านั้นนะครับ มันมีโอกาสเกิดขึ้นในระดับ Architect หรือใน Microservices ด้วยซึ่งบางครั้งถ้าเทสเทพ ๆ ก็อาจจะเจอตั้งแต่ตอนที่เราทำ Integration เลย

ผิดพลาดตรงไหน ชี้แนะได้เลยครับผม

--

--

Sakul Montha
SCB TechX

Chief Product Officer, a man who’s falling in love with the galaxy.