C ++原子列表容器

托马斯·斯伯伯

我在玩,std::atomic但是我认为我不完全理解这个概念。我想知道为什么没有原子容器。所以我玩了一点。首先,我尝试了以下方法:

std::atomic<std::list<int> > atomicList;

但正如其他人已经指出的那样,这是行不通的,因为构造函数是noexcept因此,我创建了某种hack:

template<class T>
class MyList
{
public:
    //Make sure that no exception is thrown
    MyList() noexcept
        try: l()
    {}catch(...) {}

    void push_back(const T &t) { l.push_back(t); }

    void pop_front() { l.pop_front(); }

    size_t size() const { return l.size(); }

private:
    list<T> l;

};

atomic<MyList<int> > atomicList;

现在,我使用它,但是发现它无法正常工作,并且出现了分段错误错误。

有人可以解释为什么无法通过这种方式创建原子列表吗?

编辑:如果有人想看看我的测试程序如何看起来更好地理解:

#include <list>
#include <thread>
#include <sys/time.h>
#include <iostream>
#include <atomic>

using namespace std;

template<class T>
class MyList
{

public:
    MyList() noexcept
        try: l()
    {}catch(...) {}

    void push_back(const T &t) { l.push_back(t); }

    void pop_front() { l.pop_front(); }

    size_t size() const { return l.size(); }

private:
    list<T> l;

};

atomic<MyList<int> > l;

void work()
{
    for(unsigned int i = 0; i < 100000; ++i)
    {
        //Called operator()
        ((MyList<int>&)l).push_back(i);
        ((MyList<int>&)l).push_back(((MyList<int>&)l).size());
        ((MyList<int>&)l).pop_front();
    }
}

int main(int argc, char *args[])
{
    struct timeval time1;
    struct timeval time2;
    gettimeofday(&time1, 0);
    thread t1(work);
    thread t2(work);
    thread t3(work);
    thread t4(work);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    gettimeofday(&time2, 0);
    cout<<((time2.tv_sec-time1.tv_sec)+double(time2.tv_usec-time1.tv_usec)/1000000)<<endl;
}
用户名

第一个也是最重要的问题:这可能行不通。您需要围绕成员函数的执行进行同步,而不是围绕获取列表进行同步。std::atomic甚至都不像您所需要的。

关于你试图实现,铸造atomic<T>T&不能做任何事情合理。

即使有意义,这样的转换也会完全忘记对象的原子性,因此您对引用所做的任何操作都不会是原子操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章