เป็นไปไม่ได้ที่เธรดสองตัว (หรือมากกว่า) จะได้รับการล็อคในเวลาเดียวกัน มีวิธีการซิงโครไนซ์ไม่กี่ชนิดเช่น:
การรอคอยที่ใช้งาน - ล็อคการหมุน
pseudocode:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG เป็นตัวอย่างของการทำงานแบบปรมาณู (มีอยู่ในสถาปัตยกรรม x86) ซึ่งตั้งค่าใหม่เป็นครั้งแรกสำหรับตัวแปร "ล็อค" แล้วส่งคืนค่าเดิม อะตอมมิกหมายความว่ามันไม่สามารถขัดจังหวะ - ในตัวอย่างข้างต้นระหว่างการตั้งค่าใหม่และเก่าคืน อะตอม - ผลลัพธ์ที่กำหนดขึ้นไม่ว่าอะไรจะเกิดขึ้น
2. Your code
3. lock = 0; - exit protocol
เมื่อล็อกเท่ากับ 0 เธรดอื่นสามารถเข้าสู่ส่วนที่สำคัญ - ในขณะที่ลูปสิ้นสุด
การระงับเธรด - ตัวอย่างเช่นการนับเซมาฟอร์นับ
มีสองการดำเนินงานของอะตอมที่มีอยู่.Wait()
และและเรามีจำนวนเต็มตัวแปรช่วยให้เรียกว่า.Signal()
int currentValue
Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;
Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;
ตอนนี้การแก้ปัญหาส่วนที่สำคัญเป็นเรื่องง่าย:
pseudocode:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
โดยปกติ API เธรดการเขียนโปรแกรมของคุณควรให้ความสามารถในการระบุเธรดที่เกิดขึ้นพร้อมกันสูงสุดในเซกเมนต์วิกฤติส่วน เห็นได้ชัดว่ามีการซิงโครไนซ์ประเภทอื่น ๆ ในระบบหลายเธรด (mutex, จอภาพ, สัญญาณเซมาฟอร์และอื่น ๆ ) แต่ก็มีพื้นฐานอยู่เหนือแนวคิด เราอาจโต้แย้งได้ว่าวิธีการที่ใช้เธรดที่หยุดทำงานชั่วคราวนั้นน่าจะดีกว่าการรอคอย (ดังนั้น cpu จะไม่สูญเปล่า) - มันไม่ได้เป็นความจริงเสมอไป เมื่อเธรดถูกระงับ - การดำเนินการที่แพงเรียกว่า context switch เกิดขึ้น อย่างไรก็ตามมีเหตุผลเมื่อรอเวลาสั้น (จำนวนเธรด ~ จำนวนแกน)