ในขณะที่ mutex อาจถูกใช้เพื่อแก้ไขปัญหาอื่น ๆ เหตุผลหลักที่พวกเขามีอยู่คือการให้การยกเว้นซึ่งกันและกันและจึงแก้สิ่งที่เรียกว่าสภาพการแข่งขัน เมื่อสอง (หรือมากกว่า) กระทู้หรือกระบวนการกำลังพยายามเข้าถึงตัวแปรเดียวกันพร้อมกันเรามีศักยภาพสำหรับสภาพการแข่งขัน พิจารณารหัสต่อไปนี้
//somewhere long ago, we have i declared as int
void my_concurrently_called_function()
{
i++;
}
ฟังก์ชั่นภายในของฟังก์ชั่นนี้ดูเรียบง่าย มันเป็นเพียงคำสั่งเดียว อย่างไรก็ตามการเทียบเท่าภาษาเทียมประกอบโดยทั่วไปอาจเป็น:
load i from memory into a register
add 1 to i
store i back into memory
เนื่องจากคำสั่งภาษาแอสเซมบลีที่เทียบเท่านั้นจำเป็นสำหรับการดำเนินการเพิ่มบน i เราจึงบอกว่าการเพิ่ม i คือการดำเนินการที่ไม่ใช่เชิงอรรถ การดำเนินการแบบอะตอมมิกเป็นสิ่งที่สามารถทำให้เสร็จสมบูรณ์ได้บนฮาร์ดแวร์ที่มีการรับประกันว่าจะไม่ถูกขัดจังหวะเมื่อเริ่มดำเนินการคำสั่ง การเพิ่มขึ้นของ i ประกอบไปด้วยโซ่ของ 3 อะตอมคำแนะนำ ในระบบพร้อมกันที่หลายเธรดกำลังเรียกใช้ฟังก์ชันปัญหาจะเกิดขึ้นเมื่อเธรดอ่านหรือเขียนในเวลาที่ไม่ถูกต้อง ลองนึกภาพเรามีสองเธรดที่ทำงานพร้อมกันและหนึ่งเรียกฟังก์ชันทันทีหลังจากที่อื่น สมมุติว่าเรามีค่าเริ่มต้นที่ 0 ด้วยสมมติว่าเรามีรีจิสเตอร์มากมายและเธรดทั้งสองนั้นใช้รีจิสเตอร์ที่แตกต่างกันโดยสิ้นเชิงดังนั้นจึงไม่มีการชนกัน เวลาที่แท้จริงของเหตุการณ์เหล่านี้อาจเป็น:
thread 1 load 0 into register from memory corresponding to i //register is currently 0
thread 1 add 1 to a register //register is now 1, but not memory is 0
thread 2 load 0 into register from memory corresponding to i
thread 2 add 1 to a register //register is now 1, but not memory is 0
thread 1 write register to memory //memory is now 1
thread 2 write register to memory //memory is now 1
สิ่งที่เกิดขึ้นคือเรามีสองเธรดที่เพิ่มขึ้นพร้อมกันฟังก์ชันของเราถูกเรียกสองครั้ง แต่ผลลัพธ์ไม่สอดคล้องกับข้อเท็จจริงนั้น ดูเหมือนว่าฟังก์ชั่นจะถูกเรียกเพียงครั้งเดียว นี่เป็นเพราะอะตอมมิก "เสีย" ที่ระดับเครื่องความหมายของเธรดสามารถขัดจังหวะซึ่งกันและกันหรือทำงานร่วมกันในเวลาที่ผิด
เราต้องการกลไกในการแก้ปัญหานี้ เราจำเป็นต้องสั่งซื้อสินค้าตามคำแนะนำข้างต้น กลไกหนึ่งที่พบบ่อยคือการบล็อกเธรดทั้งหมดยกเว้นหนึ่งหัวข้อ Pthread mutex ใช้กลไกนี้
เธรดใด ๆ ที่ต้องรันโค้ดบางบรรทัดซึ่งอาจแก้ไขค่าที่แชร์โดยเธรดอื่นอย่างไม่ปลอดภัยในเวลาเดียวกัน (การใช้โทรศัพท์เพื่อพูดคุยกับภรรยาของเขา) อันดับแรกควรทำให้ได้รับการล็อคบน mutex ด้วยวิธีนี้เธรดใด ๆ ที่ต้องการเข้าถึงข้อมูลที่แบ่งใช้ต้องผ่านการล็อก mutex จากนั้นเธรดจะสามารถเรียกใช้งานโค้ดได้ ส่วนของรหัสนี้เรียกว่าส่วนที่สำคัญ
เมื่อเธรดดำเนินการส่วนที่สำคัญแล้วควรปล่อยการล็อกบน mutex เพื่อให้เธรดอื่นสามารถรับการล็อกบน mutex
แนวคิดของการมี mutex นั้นดูแปลก ๆ เมื่อพิจารณาจากมนุษย์ที่ต้องการการเข้าถึงวัตถุทางกายภาพจริง แต่เพียงอย่างเดียว แต่เมื่อเขียนโปรแกรมเราต้องตั้งใจ เธรดและกระบวนการที่เกิดขึ้นพร้อมกันนั้นไม่มีการอบรมทางสังคมและวัฒนธรรมที่เราทำดังนั้นเราต้องบังคับให้พวกเขาแบ่งปันข้อมูลอย่างดี
ดังนั้นเทคนิคการพูด mutex ทำงานอย่างไร มันไม่ได้รับผลกระทบจากสภาพการแข่งขันเดียวกันกับที่เราพูดถึงก่อนหน้านี้หรือไม่? pthread_mutex_lock () นั้นซับซ้อนกว่านี้เล็กน้อยซึ่งเป็นการเพิ่มขึ้นของตัวแปรอย่างง่ายหรือไม่?
ในทางเทคนิคแล้วเราต้องการการสนับสนุนด้านฮาร์ดแวร์เพื่อช่วยเหลือเรา นักออกแบบฮาร์ดแวร์ให้คำแนะนำเครื่องที่ทำมากกว่าหนึ่งสิ่ง แต่รับประกันเป็นอะตอม ตัวอย่างคลาสสิกของคำสั่งดังกล่าวคือชุดการทดสอบและชุด (TAS) เมื่อพยายามรับการล็อคทรัพยากรเราอาจใช้ TAS อาจตรวจสอบเพื่อดูว่าค่าในหน่วยความจำเท่ากับ 0 หรือไม่หากเป็นเช่นนั้นก็จะเป็นสัญญาณของเราว่าทรัพยากรนั้นกำลังใช้งานอยู่และเราไม่ได้ทำอะไรเลย เรารอด้วยกลไกบางอย่าง pthreads mutex จะทำให้เราเข้าสู่คิวพิเศษในระบบปฏิบัติการและจะแจ้งให้เราทราบเมื่อมีทรัพยากรพร้อมใช้งานระบบ Dumber อาจทำให้เราต้องวนรอบการปั่นที่แน่นหนา . หากค่าในหน่วยความจำไม่ใช่ 0 TAS จะตั้งค่าตำแหน่งเป็นค่าอื่นที่ไม่ใช่ 0 โดยไม่ต้องใช้คำสั่งอื่น มัน' เหมือนการรวมคำสั่งสองชุดเข้าด้วยกันเป็น 1 เพื่อให้อะตอมมิกซิตี้ของเรา ดังนั้นการทดสอบและการเปลี่ยนแปลงค่า (หากมีการเปลี่ยนแปลงที่เหมาะสม) ไม่สามารถถูกขัดจังหวะเมื่อเริ่มต้นขึ้น เราสามารถสร้าง mutex ได้บนคำสั่งดังกล่าว
หมายเหตุ: บางส่วนอาจมีลักษณะคล้ายกับคำตอบก่อนหน้า ฉันยอมรับคำเชิญของเขาเพื่อแก้ไขเขาชอบวิธีดั้งเดิมเหมือนเดิมดังนั้นฉันจึงรักษาสิ่งที่ฉันมีซึ่งใช้คำฟุ่มเฟือยเล็กน้อย