Go Academy · บทเรียน

ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย

ใช้แฟล็ก -race และหลีกเลี่ยงภาวะแข่งขันของข้อมูล

บทเรียน 4 จาก 413 ขั้นตอน

ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

ภาวะข้อมูลแข่งกันคืออะไร

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

การเปิดใช้งานตัวตรวจจับภาวะข้อมูลแข่งกัน

เรียกใช้หรือทดสอบด้วย -race เพื่อเปิดใช้งานตัวตรวจจับภาวะข้อมูลแข่งกันในตัวของ Go:

go run -race main.go
go test -race ./...

ผลลัพธ์จากตัวตรวจจับภาวะข้อมูลแข่งกัน

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

ต้นทุนด้านประสิทธิภาพ

ตัวตรวจจับภาวะข้อมูลแข่งกันเพิ่มการใช้หน่วยความจำประมาณ 5-10 เท่า และทำให้การทำงานช้าลงประมาณ 2-20 เท่า ควรเรียกใช้ใน CI และสภาพแวดล้อมการทดสอบ ไม่ใช่ในบิลด์สำหรับใช้งานจริง

รูปแบบที่ปลอดภัยที่พบบ่อย: การดำเนินการแบบอะตอมิก

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

var counter int64
atomic.AddInt64(&counter, 1)
fmt.Println(atomic.LoadInt64(&counter))

รูปแบบที่ปลอดภัยที่พบบ่อย: การถือครองผ่านช่องสัญญาณ

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

ch := make(chan []byte)
go func() { ch <- makeData() }()
data := <-ch // sole owner now

รูปแบบที่ปลอดภัยที่พบบ่อย: ข้อมูลที่เปลี่ยนแปลงไม่ได้

ข้อมูลแบบอ่านอย่างเดียวที่ใช้ร่วมกันระหว่างโกโรทีนมีความปลอดภัย ควรเขียนข้อมูลให้เสร็จก่อนเริ่มโกโรทีน หรือประสานงานการเขียน String และค่า [N]T สามารถใช้ร่วมกันได้อย่างปลอดภัยหลังจากสร้างเสร็จแล้ว

การตรวจจับภาวะข้อมูลแข่งกันในการทดสอบ

ตัวตรวจจับภาวะข้อมูลแข่งกันทำงานร่วมกับ go test -race เขียนการทดสอบที่เรียกใช้เส้นทางการทำงานพร้อมกัน ตัวตรวจจับจะพบภาวะข้อมูลแข่งกันที่การทดสอบแบบลำดับที่ไม่ก่อปัญหาอาจตรวจไม่พบ

sync.atomic เทียบกับ mutex

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

ความสัมพันธ์เกิดก่อน

Go รับประกันความสัมพันธ์แบบเกิดก่อนสำหรับการดำเนินการกับช่องสัญญาณ, mutex Lock/Unlock และ sync.Once.Do การดำเนินการภายในโกโรทีนเดียวกันจะเรียงลำดับตามลำดับการทำงาน

การใช้แคชร่วมกันโดยไม่ตั้งใจ

โกโรทีนสองตัวที่ปรับปรุงหน่วยความจำตำแหน่งใกล้กัน เช่น ฟิลด์ต่างกันในบรรทัดแคชเดียวกัน อาจทำให้แคชถูกโหลดซ้ำไปมาอย่างหนัก หากการทำโปรไฟล์แสดงว่ามีการแย่งชิงทรัพยากรในโครงสร้างใดโดยเฉพาะ ให้เติมพื้นที่ในโครงสร้างนั้นด้วย [64]byte

ตรวจสอบอย่างรวดเร็ว

แฟล็กใดเปิดใช้งานตัวตรวจจับภาวะข้อมูลแข่งกันของ Go

สรุป: ตัวตรวจจับภาวะข้อมูลแข่งกันและรูปแบบที่ปลอดภัย

ประเด็นสำคัญ:

  • เรียกใช้ go test -race ใน CI เสมอ
  • รูปแบบที่ปลอดภัย ได้แก่ ช่องสัญญาณ, mutex, การดำเนินการแบบอะตอมิก และข้อมูลที่เปลี่ยนแปลงไม่ได้
  • ผลลัพธ์ของตัวตรวจจับแสดงสแตกของโกโรทีนที่เกี่ยวข้องโดยตรง
  • ห้ามใช้ -race ในบิลด์สำหรับใช้งานจริง
เริ่มต้นได้ฟรี

เรียนรู้ Go ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย”

ใช้แฟล็ก -race และหลีกเลี่ยงภาวะแข่งขันของข้อมูล คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม

ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. sync.Mutex และ sync.RWMutex
  2. sync.WaitGroup
  3. sync.Once และ sync.Map
  4. ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย
← กลับไปที่ Go Academy