Sto giocando con std::atomic
ma penso di non aver capito completamente il concetto. Mi chiedo perché non ci sono contenitori atomici. Così ho giocato un po 'in giro. Per prima cosa ho provato quanto segue:Contenitore di lista atomica C++
std::atomic<std::list<int> > atomicList;
Ma, come già altre persone sottolineato che questo non funziona perché il costruttore è noexcept
. Così ho creato una sorta di 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;
Ora ho lavorato con lui, ma ho scoperto che non funziona correttamente e si verificano errori di segmentation fault.
Qualcuno può spiegare perché non è possibile creare una lista atomica in questo modo?
EDIT: Se qualcuno vuole vedere come il mio programma di test sembra davvero per una migliore comprensione:
#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 Capisco. Quindi è effettivamente possibile * convertire * un container stl in atomico? O è necessario crearlo da zero? –
@Thomas: potresti provare a scrivere un adattatore per contenitore, ma penso che sarebbe molto meglio pensare in termini di "scrittura da zero, ma forse utilizzare internamente un contenitore standard". Soprattutto perché il concetto di 'Container' è in realtà * impossibile * da rendere atomico, a meno che il loro' value_type' sia un oggetto specializzato che coopera con il contenitore per comportarsi atomicamente (es. Come potrebbe 'C [i] = x;' può essere implementato come un'operazione atomica?). – Hurkyl