Bạn đã nghe nhầm. Nó có thể "i++"
an toàn theo luồng đối với một trình biên dịch cụ thể và kiến trúc bộ xử lý cụ thể nhưng nó không bắt buộc trong các tiêu chuẩn. Trên thực tế, vì đa luồng không phải là một phần của tiêu chuẩn ISO C hoặc C ++ (a) , bạn không thể coi bất cứ thứ gì là an toàn cho luồng dựa trên những gì bạn nghĩ rằng nó sẽ biên dịch xuống.
Nó khá khả thi ++i
có thể biên dịch thành một chuỗi tùy ý như:
load r0,[i] ; load memory into reg 0
incr r0 ; increment reg 0
stor [i],r0 ; store reg 0 back to memory
sẽ không an toàn theo luồng trên CPU (tưởng tượng) của tôi không có hướng dẫn tăng bộ nhớ. Hoặc nó có thể thông minh và biên dịch nó thành:
lock ; disable task switching (interrupts)
load r0,[i] ; load memory into reg 0
incr r0 ; increment reg 0
stor [i],r0 ; store reg 0 back to memory
unlock ; enable task switching (interrupts)
nơi lock
vô hiệu hóa và unlock
cho phép ngắt. Tuy nhiên, ngay cả khi đó, điều này có thể không an toàn theo luồng trong một kiến trúc có nhiều hơn một trong các CPU này chia sẻ bộ nhớ ( lock
chỉ có thể vô hiệu hóa các ngắt cho một CPU).
Bản thân ngôn ngữ (hoặc các thư viện cho nó, nếu nó không được tích hợp sẵn trong ngôn ngữ) sẽ cung cấp các cấu trúc an toàn cho luồng và bạn nên sử dụng những cấu trúc đó thay vì phụ thuộc vào sự hiểu biết của bạn (hoặc có thể hiểu nhầm) về mã máy nào sẽ được tạo.
Những thứ như Java synchronized
và pthread_mutex_lock()
(có sẵn cho C / C ++ trong một số hệ điều hành) là những gì bạn cần xem xét (a) .
(a) Câu hỏi này được đặt ra trước khi tiêu chuẩn C11 và C ++ 11 được hoàn thành. Những lần lặp đó hiện đã giới thiệu hỗ trợ phân luồng vào các đặc tả ngôn ngữ, bao gồm các kiểu dữ liệu nguyên tử (mặc dù chúng và các luồng nói chung, là tùy chọn, ít nhất là trong C).