Tôi đang viết con trỏ được chia sẻ xâm nhập và tôi đang sử dụng các cơ sở C++ 11 <atomic>
để tham khảo. Dưới đây là các mảnh vỡ có liên quan của mã của tôi:C++ 11 nguyên tử và số tham chiếu con trỏ chia sẻ xâm nhập
//...
mutable std::atomic<unsigned> count;
//...
void
SharedObject::addReference() const
{
std::atomic_fetch_add_explicit (&count, 1u,
std::memory_order_consume);
}
void
SharedObject::removeReference() const
{
bool destroy;
destroy = std::atomic_fetch_sub_explicit (&count, 1u,
std::memory_order_consume) == 1;
if (destroy)
delete this;
}
Tôi đã bắt đầu với memory_order_acquire
và memory_order_release
đầu tiên nhưng sau đó tôi đã thuyết phục bản thân mình rằng memory_order_consume
nên đủ tốt. Sau khi cân nhắc thêm, có vẻ như với tôi rằng ngay cả memory_order_relaxed
cũng sẽ hoạt động.
Bây giờ, câu hỏi là liệu tôi có thể sử dụng memory_order_consume
cho các hoạt động hoặc tôi có thể sử dụng đặt hàng yếu hơn (memory_order_relaxed
) hay tôi nên sử dụng đặt hàng khắt khe hơn?
Vì bộ đếm cơ bản hoạt động như một khóa đệ quy cho câu lệnh 'delete', tôi muốn nói rằng" có được "trong' addReference' và "release" trong 'removeReference' là thứ tự đúng. Nhưng 'addReference' của bạn cũng nên đảm bảo rằng bộ đếm không phải là số không! –
@KerrekSB: Bộ đếm có thể bằng không trong 'addReference()' sau khi đối tượng được tạo đầu tiên trước khi nó được gán cho một 'SharedPtr <>'. Có được/phát hành ngữ nghĩa dường như nó luôn luôn hoạt động. Nhưng nó không thể sử dụng ràng buộc đặt hàng yếu hơn và tại sao không? – wilx
Về số không: Giả sử refcount là 1. Bây giờ thread 1 muốn xóa đối tượng và các cuộc gọi trừ đi. Nếu tại thời điểm này thread 2 muốn * tăng * số lượng chủ đề, nó tăng không đến một, nhưng thread 1 sẽ đi trước và xóa các đối tượng anyway. Điều đó nên tránh. –