C++原子列表容器
C++ atomic list container
我在玩std::atomic
但我想我没有完全理解这个概念。我想知道为什么没有原子容器。所以我玩了一会儿。首先,我尝试了以下方法:
std::atomic<std::list<int> > atomicList;
但是正如其他人已经指出的那样,这是行不通的,因为构造函数是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;
现在我使用它,但我发现它无法正常工作,并且出现分段错误。
有人可以解释为什么无法以这种方式创建原子列表吗?
编辑:如果有人想看看我的测试程序如何真正寻找更好的理解:
#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
甚至没有开始类似于您需要的东西。
关于您尝试的实现,对T&
进行atomic<T>
不能做任何合理的事情。
即使它有意义,这样的强制转换也会完全忘记对象的原子性,因此您对引用所做的任何事情都不会是原子操作。
((MyList<int>&)l).push_back(i);
std::atomic
不提供引用的转换运算符。如果你使用static_cast
,它甚至不会编译,但在这里C-cast直接将std::atomic<MyList<int>>
重新解释为MyList<int>
,这有充分的理由不工作。
您不能直接修改std::atomic
中的内容。您需要使用 load()
检索数据的副本,修改此副本,然后将其换回 store()
。
相关文章:
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 通过for循环使用用户输入填充列表
- C++:如何使函数只返回作为列表一部分的字符串
- 概念中的cv限定符需要表达式参数列表
- 下面是我为检测链接列表中的循环而制作的代码
- 建议在运行时将带有类实例的列表从c++导入qml
- 如何维护资源管理器项目视图中当前可见的项目列表
- 在卡萨布兰卡形成编码参数的列表
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题