2010-03-04 20 views
10

Trong nỗ lực của tôi để phát triển một lớp mẫu con trỏ yếu C++ an toàn, tôi cần kiểm tra cờ cho biết đối tượng vẫn còn sống, nếu có thì tăng số tham chiếu của đối tượng và tôi cần thực hiện cả hai bước một cách nguyên tử.Làm cách nào để so sánh và tăng tỷ lệ nguyên tử?

Tôi biết sự tồn tại của các hàm nội tại do trình biên dịch cung cấp, ví dụ _InterlockedCompareExchange() và _InterlockedIncrement(). Nhưng những gì tôi muốn là một chức năng interlockedCompareIncrement(), là có một cách hiệu quả để mô phỏng này nội tại bằng cách sử dụng nguyên thủy khác, ít nhất là trên nền tảng Windows x86?

+0

Nếu đây là trên Windows, bạn nên nói như vậy. – Gabe

Trả lời

7

Giả sử rằng value là biến cờ của bạn. Nó phải được khai báo volatile.

long curvalue; 
long newvalue; 

do 
{ 
    curvalue = value; 
    newvalue = curvalue + 1; 
} 
while(_InterlockedCompareExchange(&value, newvalue, curvalue) != curvalue); 

Như bạn thấy bạn có thể khái quát này để bất cứ loại số học bạn cần bằng cách thay đổi các hoạt động được áp dụng để tính toán newvalue.

Nếu bạn muốn so sánh hai giá trị cùng một lúc, đặt cược tốt nhất của bạn là đóng gói cả hai giá trị vào một biến duy nhất và sau đó hoạt động trên biến duy nhất đó. Vì bạn đang sử dụng cờ kết hợp với số lượng tham chiếu, tôi khuyên bạn nên sử dụng bit thấp nhất của value làm cờ 'hoạt động' và sau đó tăng/giảm 2 lần mỗi lần. Điều này cho phép bạn mã hóa cả cờ và số tham chiếu thành một biến 32 bit duy nhất.

+0

Có vẻ như những gì tôi đang tìm kiếm, tôi sẽ xem xét kỹ hơn trong đó. –

+0

+1: Tôi đang tìm kiếm hàm IncIfNot nguyên tử. Điều này cũng có thể viết với một vòng lặp và _InterlockedCompareExchange()! – mmmmmmmm

1

Nếu bạn muốn thư viện của bạn để chạy trên nhiều CPU hay nhiều máy tính cốt lõi bạn phải sử dụng sự hỗ trợ phần cứng được cung cấp bởi CPU. Dưới đây là một số tài liệu tham khảo dành cho bạn:

http://en.wikipedia.org/wiki/Test-and-set http://software.intel.com/en-us/forums/showthread.php?t=47498

Hoặc bạn phải sử dụng cơ chế cung cấp bởi hệ điều hành khóa. Chẳng hạn như

http://msdn.microsoft.com/en-us/library/ms684841%28VS.85%29.aspx hoặc http://en.wikipedia.org/wiki/POSIX_Threads

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