Không thể có hai (hoặc nhiều) chủ đề có được khóa cùng một lúc. Ví dụ, có một số loại phương thức đồng bộ hóa:
Chờ đợi tích cực - khóa quay
Mã giả:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG là một ví dụ về hoạt động nguyên tử (tồn tại trên kiến trúc x86) trước tiên đặt giá trị mới cho biến "khóa" và sau đó trả về giá trị cũ. Nguyên tử có nghĩa là nó không thể bị gián đoạn - trong ví dụ trên giữa việc đặt giá trị mới và trả lại giá trị cũ. Nguyên tử - kết quả xác định không có vấn đề gì.
2. Your code
3. lock = 0; - exit protocol
Khi khóa bằng 0, một luồng khác có thể vào phần quan trọng - trong khi vòng lặp kết thúc.
Đình chỉ chủ đề - ví dụ đếm semaphore
Tồn tại hai hoạt động nguyên tử .Wait()
và .Signal()
và chúng tôi có số nguyên biến cho phép gọi nó 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;
Bây giờ giải quyết vấn đề phần quan trọng là thực sự dễ dàng:
Mã giả:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
Thông thường API luồng lập trình của bạn sẽ cung cấp cho bạn khả năng chỉ định các luồng đồng thời tối đa trong phần quan trọng semaphore. Rõ ràng có nhiều loại đồng bộ hóa hơn trong các hệ thống đa luồng (mutex, màn hình, semaphore nhị phân, v.v.) nhưng chúng dựa trên các ý tưởng trên. Người ta có thể lập luận rằng các phương thức sử dụng tạm dừng luồng nên được ưu tiên chờ đợi hoạt động (vì vậy cpu không bị lãng phí) - không phải lúc nào cũng là sự thật. Khi luồng đang bị treo - hoạt động đắt tiền được gọi là chuyển đổi ngữ cảnh diễn ra. Tuy nhiên, thật hợp lý khi thời gian chờ là ngắn (số luồng ~ số lõi).