Я играю с std::atomic
, но я думаю, что я не совсем понял концепцию. Мне интересно, почему нет атомных контейнеров. Поэтому я немного поиграл. Сначала я попробовал следующее:C++ атомный список контейнеров
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;
Теперь я работал с ним, но я обнаружил, что он не работает должным образом, и я получаю ошибки ошибки сегментации.
Может кто-нибудь объяснить, почему это невозможно создать атомный список?
EDIT: Если кто-то хочет увидеть, как моя тестовая программа действительно выглядит для лучшего понимания:
#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;
}
OK Я понимаю. Так действительно ли можно * конвертировать * stl Container в атомарное? Или нужно создать его с нуля? –
@Thomas: Вы могли бы попытаться написать контейнерный адаптер, но я думаю, вам будет гораздо лучше подумать с точки зрения «написать его с нуля, но, возможно, использовать стандартный контейнер внутри». Тем более, что концепция 'Container' на самом деле * невозможна * для создания атома, если только их' value_type' не является специализированным объектом, который взаимодействует с контейнером, чтобы вести себя атомарно (например, как можно было бы использовать C [i] = x; 'возможно атомная операция?). – Hurkyl