ใครช่วยอธิบายง่ายๆว่าการโต้แย้งของเธรดคืออะไร?
ฉัน googled แล้ว แต่ดูเหมือนจะหาคำอธิบายง่ายๆไม่ได้
ใครช่วยอธิบายง่ายๆว่าการโต้แย้งของเธรดคืออะไร?
ฉัน googled แล้ว แต่ดูเหมือนจะหาคำอธิบายง่ายๆไม่ได้
คำตอบ:
ความขัดแย้งของเธรดโดยพื้นฐานคือเงื่อนไขที่เธรดหนึ่งกำลังรอการล็อก / อ็อบเจ็กต์ที่เธรดอื่นกำลังยึดอยู่ ดังนั้นเธรดที่รอนี้จึงไม่สามารถใช้อ็อบเจกต์นั้นได้จนกว่าเธรดอื่นจะปลดล็อกอ็อบเจ็กต์นั้น
คำตอบหลายข้อดูเหมือนจะมุ่งเน้นไปที่การโต้เถียงเรื่องการล็อก แต่การล็อกไม่ใช่แหล่งข้อมูลเดียวที่สามารถประสบกับความขัดแย้งได้ การโต้แย้งเกิดขึ้นเมื่อเธรดสองเธรดพยายามเข้าถึงทรัพยากรเดียวกันหรือทรัพยากรที่เกี่ยวข้องในลักษณะที่เธรดที่แข่งขันกันอย่างน้อยหนึ่งเธรดทำงานช้ากว่าที่จะเป็นหากเธรดอื่นไม่ทำงาน
ตัวอย่างที่ชัดเจนที่สุดของการทะเลาะวิวาทอยู่ที่การล็อก หากเธรด A มีการล็อกและเธรด B ต้องการรับล็อกเดียวกันเธรด B จะต้องรอจนกว่าเธรด A จะคลายล็อก
ตอนนี้นี่เป็นเฉพาะแพลตฟอร์ม แต่เธรดอาจพบการชะลอตัวแม้ว่าจะไม่ต้องรอให้เธรดอื่นคลายการล็อก! เนื่องจากการล็อกป้องกันข้อมูลบางประเภทและข้อมูลเองก็มักจะถูกโต้แย้งเช่นกัน
ตัวอย่างเช่นพิจารณาเธรดที่ได้รับการล็อกปรับเปลี่ยนอ็อบเจ็กต์จากนั้นคลายล็อกและทำสิ่งอื่น ๆ หากเธรดสองเธรดกำลังทำสิ่งนี้แม้ว่าเธรดจะไม่เคยต่อสู้เพื่อล็อกเธรดอาจทำงานช้ากว่าที่ควรจะเป็นมากหากเธรดเดียวทำงาน
ทำไม? สมมติว่าแต่ละเธรดทำงานบนแกนของตัวเองบน CPU x86 ที่ทันสมัยและคอร์ไม่แชร์แคช L2 ด้วยเธรดเดียววัตถุอาจยังคงอยู่ในแคช L2 เกือบตลอดเวลา เมื่อเธรดทั้งสองทำงานทุกครั้งที่เธรดหนึ่งแก้ไขอ็อบเจ็กต์เธรดอื่นจะพบว่าข้อมูลไม่ได้อยู่ในแคช L2 เนื่องจาก CPU อื่นทำให้บรรทัดแคชไม่ถูกต้อง ตัวอย่างเช่นใน Pentium D จะทำให้โค้ดทำงานที่ความเร็ว FSB ซึ่งน้อยกว่าความเร็วแคช L2 มาก
เนื่องจากความขัดแย้งอาจเกิดขึ้นได้แม้ว่าตัวล็อคจะไม่ได้รับการโต้แย้งก็ตามการโต้แย้งก็อาจเกิดขึ้นได้เมื่อไม่มีการล็อก ตัวอย่างเช่นสมมติว่า CPU ของคุณรองรับการเพิ่มตัวแปรแบบ 32 บิตแบบอะตอม หากเธรดหนึ่งยังคงเพิ่มและลดตัวแปรตัวแปรจะร้อนในแคชตลอดเวลา หากสองเธรดทำเช่นนั้นแคชของพวกเขาจะโต้แย้งในการเป็นเจ้าของหน่วยความจำที่ถือตัวแปรนั้นและการเข้าถึงจำนวนมากจะช้าลงเนื่องจากโปรโตคอลการทำงานร่วมกันของแคชทำงานเพื่อรักษาความปลอดภัยของการเป็นเจ้าของคอร์แต่ละบรรทัดของแคช
แดกดันโดยทั่วไปแล้วการล็อคจะช่วยลดความขัดแย้ง ทำไม? เนื่องจากหากไม่มีการล็อกเธรดสองเธรดสามารถทำงานบนอ็อบเจ็กต์หรือคอลเลคชันเดียวกันและทำให้เกิดข้อขัดแย้งมากมาย (ตัวอย่างเช่นมีคิวที่ไม่มีการล็อก) การล็อกจะมีแนวโน้มที่จะยกเลิกการกำหนดเวลาเธรดที่แข่งขันกันโดยปล่อยให้เธรดที่ไม่แข่งขันกันทำงานแทน หากเธรด A มีล็อกและเธรด B ต้องการล็อกเดียวกันการใช้งานสามารถรันเธรด C แทน หากเธรด C ไม่จำเป็นต้องมีการล็อกนั้นการขัดแย้งในอนาคตระหว่างเธรด A และ B สามารถหลีกเลี่ยงได้ชั่วขณะ (แน่นอนว่าสิ่งนี้ถือว่ามีเธรดอื่น ๆ ที่สามารถทำงานได้มันจะไม่ช่วยอะไรหากวิธีเดียวที่ระบบโดยรวมสามารถสร้างความก้าวหน้าที่เป็นประโยชน์คือการรันเธรดที่โต้แย้ง)
จากที่นี่ :
ความขัดแย้งเกิดขึ้นเมื่อเธรดกำลังรอทรัพยากรที่ไม่พร้อมใช้งาน มันทำให้การเรียกใช้โค้ดของคุณช้าลง แต่สามารถล้างข้อมูลได้เมื่อเวลาผ่านไป
การหยุดชะงักเกิดขึ้นเมื่อเธรดกำลังรอรีซอร์สที่เธรดที่สองถูกล็อกและเธรดที่สองกำลังรอรีซอร์สที่เธรดแรกถูกล็อก มากกว่าสองเธรดสามารถเกี่ยวข้องกับการหยุดชะงัก การหยุดชะงักไม่เคยแก้ไขตัวเอง บ่อยครั้งที่ทำให้แอปพลิเคชันทั้งหมดหรือส่วนที่ประสบกับการหยุดชะงักหยุดชะงัก
ฉันคิดว่าควรมีคำชี้แจงจาก OP เกี่ยวกับพื้นหลังของคำถาม - ฉันคิดได้ 2 คำตอบ (แม้ว่าฉันแน่ใจว่ามีส่วนเพิ่มเติมในรายการนี้):
หากคุณกำลังอ้างถึง "แนวคิด" ทั่วไปของการโต้แย้งเธรดและวิธีที่สามารถนำเสนอในแอปพลิเคชันได้ฉันขอเลื่อนคำตอบโดยละเอียดของ @ DavidSchwartz ข้างต้น
นอกจากนี้ยังมีตัวนับประสิทธิภาพ '.NET CLR Locks and Threads: Total # of Contentions' ตามที่นำมาจากคำอธิบาย PerfMon สำหรับตัวนับนี้ถูกกำหนดเป็น:
ตัวนับนี้แสดงจำนวนครั้งทั้งหมดที่เธรดใน CLR พยายามรับล็อกที่มีการจัดการไม่สำเร็จ ล็อคที่มีการจัดการสามารถรับได้หลายวิธี โดยคำสั่ง "lock" ใน C # หรือโดยเรียก System.Monitor.Enter หรือโดยใช้ MethodImplOptions.Synchronized แอตทริบิวต์ที่กำหนดเอง
... และฉันแน่ใจว่าคนอื่น ๆ สำหรับ OS'es และกรอบแอปพลิเคชันอื่น ๆ
คุณมี 2 กระทู้ เธรด A และเธรด B คุณยังมีวัตถุ C
ขณะนี้ A กำลังเข้าถึงวัตถุ C และได้ทำการล็อควัตถุนั้น B ต้องการเข้าถึงวัตถุ C แต่ไม่สามารถทำได้จนกว่า A จะปลดล็อกวัตถุ C
อีกคำหนึ่งอาจเกิดขึ้นพร้อมกัน เป็นเพียงความคิดของเธรดสองชุดขึ้นไปที่พยายามใช้ทรัพยากรเดียวกัน
การโต้แย้งสำหรับฉันคือการแข่งขันระหว่าง 2 เธรดขึ้นไปบนทรัพยากรที่ใช้ร่วมกัน ทรัพยากรอาจเป็นตัวล็อกตัวนับเป็นต้นการแข่งขันหมายถึง "ใครได้ก่อน" เธรดมากขึ้นการโต้แย้งมากขึ้น การเข้าถึงทรัพยากรบ่อยขึ้นการโต้แย้งก็มากขึ้น
ลองนึกภาพสถานการณ์ต่อไปนี้ คุณกำลังเตรียมตัวสำหรับการตรวจครั้งสุดท้ายของวันพรุ่งนี้และรู้สึกหิวเล็กน้อย ดังนั้นคุณให้เงินน้องชายของคุณสิบเหรียญและขอให้เขาซื้อพิซซ่าให้คุณ กรณีนี้คุณเป็นกระทู้หลักและน้องชายของคุณเป็นกระทู้เด็ก เมื่อได้รับคำสั่งซื้อของคุณแล้วทั้งคุณและพี่ชายของคุณจะทำงานของพวกเขาไปพร้อมกัน (เช่นเรียนและซื้อพิซซ่า) ตอนนี้เรามีสองกรณีที่ต้องพิจารณา ขั้นแรกพี่ชายของคุณจะนำพิซซ่าของคุณกลับมาและยุติลงในขณะที่คุณเรียนอยู่ ในกรณีนี้คุณสามารถหยุดเรียนและเพลิดเพลินกับพิซซ่าได้ อย่างที่สองคุณเรียนให้จบก่อนเวลาและนอน (เช่นงานที่ได้รับมอบหมายสำหรับวันนี้ - เรียนเพื่อสอบปลายภาคของวันพรุ่งนี้ - เสร็จสิ้น) ก่อนที่พิซซ่าจะวางจำหน่าย แน่นอนคุณนอนไม่หลับ มิฉะนั้นคุณจะไม่มีโอกาสได้กินพิซซ่า
ดังตัวอย่างทั้งสองกรณีให้ความหมายของการแข่งขันกัน
การช่วงชิงเธรดยังมีผลต่อการดำเนินการ I / O ตัวอย่างเมื่อเธรดที่รอการอ่านไฟล์สามารถพิจารณาได้ว่าเป็นการโต้แย้ง ใช้พอร์ตเสร็จสิ้น I / O เป็นโซลูชัน
ล็อกการช่วงชิงเกิดขึ้นเมื่อเธรดพยายามที่จะรับล็อกไปยังอ็อบเจ็กต์ที่เธรดอื่นได้รับมาแล้ว * จนกว่าวัตถุจะถูกปล่อยออกเธรดจะถูกบล็อก (กล่าวอีกนัยหนึ่งก็คืออยู่ในสถานะกำลังรอ) ในบางกรณีสิ่งนี้อาจนำไปสู่การดำเนินการแบบอนุกรมซึ่งส่งผลเสียต่อแอปพลิเคชัน