std :: atomic达到什么程度?

问题描述 投票:0回答:2

[在Sean Parent https://youtu.be/W2tWOdzgXHA在33:41的C ++ Seasoning视频中,当他们开始谈论“没有原始同步原语”时,他举了一个例子来说明使用原始同步原语我们会弄错它。该示例是写类的错误副本:

template <typename T>
class bad_cow {
    struct object_t {
        explicit object_t(const T& x) : data_m(x) { ++count_m; }
        atomic<int> count_m;
        T data_m;
    };
    object_t* object_m;

public:
    explicit bad_cow(const T& x) : object_m(new object_t(x)) { }
    ~bad_cow() { if (0 == --object_m->count_m) delete object_m; }
    bad_cow(const bad_cow& x) : object_m(x.object_m) { ++object_m->count_m; }

    bad_cow& operator=(const T& x) {
        if (object_m->count_m == 1) {
            // label #2
            object_m->data_m = x; 
        } else {
            object_t* tmp = new object_t(x);
            --object_m->count_m; // bug #1
            // this solves bug #1:
            // if (0 == --object_m->count_m) delete object_m;
            object_m = tmp;
        }
        return *this;
    }
};

然后他要求观众找到错误,即他确认的错误#1。

但是我猜,一个更明显的错误是,当某个线程将要执行执行我用标签#2表示的代码行时,突然之间,其他线程只是破坏了该对象,而析构函数是调用,删除object_m。因此,第一个线程将遇到一个已删除的内存位置。

我对吗?我似乎不是这样!

c++ c++11
2个回答
0
投票

其他线程只是破坏对象,而析构函数是调用,删除object_m。因此,第一个线程将遇到删除的内存位置。

我对吗?我似乎不是这样!


0
投票

您的异议并不成立,因为当时*this指向该对象且计数为1。除非某人未正确玩此游戏,否则计数器无法达到0(但在任何情况下都可能发生) 。

© www.soinside.com 2019 - 2024. All rights reserved.