ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย
ใช้แฟล็ก -race และหลีกเลี่ยงภาวะแข่งขันของข้อมูล
ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- sync.Mutex และ sync.RWMutex
- sync.WaitGroup
- sync.Once และ sync.Map
- ตัวตรวจจับภาวะแข่งขันและรูปแบบที่ปลอดภัย