2011-12-06 14 views
5

Tôi có một số mã đa luồng (xem câu hỏi Windows API Thread Pool simple example) mà tôi đang sử dụng bộ đếm để xác định chuỗi.InterlockedIncrement vs EnterCriticalSection/counter ++/LeaveCriticalSection

Tôi đã được khuyên nên sử dụng một InterlockedIncrement để tăng bộ đếm này trong chức năng gọi lại của luồng. Tuy nhiên điều này dường như không khóa đúng biến, vì tôi gặp phải một số vấn đề tương tranh. Tôi thay thế các InterlockedIncrement bằng cách sử dụng một phần quan trọng bằng tay: EnterCriticalSection/counter ++/LeaveCriticalSection và điều này bây giờ hoạt động hoàn hảo.

Tại sao lại như vậy? Không phải là hai lựa chọn được cho là hoàn toàn tương đương? Lưu ý rằng tôi đang nói về việc khởi chạy chỉ một vài (khoảng 10) chuỗi.

+0

Theo cách nào dường như không khóa đúng biến? Bạn gặp phải sự cố đồng thời nào? – LukeH

+0

'InterlockedIncrement' và bạn bè không cần khóa. Các hướng dẫn lắp ráp đơn thực hiện. Bạn có thể mô tả thêm về các vấn đề bạn đang thấy không? – Nate

+0

LukeH: bộ đếm không phải lúc nào cũng đưa ra một dãy số nguyên liên tục tăng dần. Đôi khi bộ đếm, bắt đầu từ 0, đang thực hiện: 0 1 2 2 4 5 ... – WhitAngl

Trả lời

26

Mã của bạn không sử dụng InterlockedIncrement chính xác.

InterlockedIncrement(&(thread.threadCount)); 
DWORD tid = (thread.threadCount-1)%thread.size(); 

này thực hiện một tăng nguyên tử của thread.threadCount, nhưng thay vì tiết kiệm giá trị nguyên tử-tăng lên, bạn lờ nó đi và quay trở lại thread.threadCount biến (có thể đã được tăng lên bởi thread khác trong khi chờ đợi).

Trong trường hợp của bạn, điều xảy ra là hai luồng đã thực hiện InterlockedIncrement gần như đồng thời, tăng từ 1 lên 2, sau đó 2 đến 3. Cả hai chủ đề sau đó đọc thread.threadCount và nhận 3 trở lại (sau đó trừ 1 để có kết quả cuối cùng của 2).

Mã đúng là

LONG tidUnique = InterlockedIncrement(&(thread.threadCount)); 
DWORD tid = (tidUnique-1)%thread.size(); 

Giá trị tăng lên duy nhất được trả về bởi InterlockedIncrement. Bạn cần phải sử dụng giá trị đó trong các tính toán của bạn nếu bạn muốn xem giá trị duy nhất.

Các vấn đề liên quan