Tho*_*ber 5 c++ containers stl list atomic
我在玩,std::atomic但我认为我并不完全理解这个概念.我想知道为什么没有原子容器.所以我玩了一下.首先我尝试了以下内容:
std::atomic<std::list<int> > atomicList;
Run Code Online (Sandbox Code Playgroud)
但正如其他人已经指出的那样,这不起作用,因为构造函数是noexcept.所以我创造了一些黑客:
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;
Run Code Online (Sandbox Code Playgroud)
现在我使用它,但我发现它无法正常工作,我得到Segmentation故障错误.
有人可以解释为什么不可能以这种方式创建原子列表?
编辑:如果有人想看看我的测试程序如何真正寻求更好的理解:
#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;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
第一个也是最重要的问题:这不可能行得通。您需要围绕成员函数的执行进行同步,而不是围绕检索列表进行同步。std::atomic甚至开始不像你所需要的。
关于您尝试的实现,强制转换atomic<T>toT&不能做任何合理的事情。
即使它有意义,这样的强制转换也会完全忘记对象的原子性,因此您对引用所做的任何操作都不会是原子操作。
| 归档时间: |
|
| 查看次数: |
3675 次 |
| 最近记录: |