Ich spiele mit std::atomic
herum, aber ich denke, dass ich das Konzept nicht völlig verstanden habe. Ich frage mich, warum es keine atomaren Container gibt. Also habe ich ein bisschen herumgespielt. Zuerst habe ich versucht, die folgenden:C++ atomischer Listencontainer
std::atomic<std::list<int> > atomicList;
Aber wie schon einige andere Leute darauf hingewiesen, dass dies nicht funktioniert, weil der Konstruktor noexcept
ist. Also habe ich eine Art von 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;
Jetzt habe ich mit ihm gearbeitet, aber ich entdeckte, dass es nicht richtig funktioniert und ich Segmentation fault Fehler erhalten.
Kann jemand bitte erklären, warum es so nicht möglich ist, eine atomare Liste zu erstellen?
EDIT: Wenn jemand will, wie wirklich mein Test sehen Programm zum besseren Verständnis aussieht:
#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 ich verstehe. Ist es also tatsächlich möglich, einen STL-Container * atomar zu konvertieren? Oder ist es notwendig, es von Grund auf neu zu erstellen? –
@Thomas: Du könntest versuchen, einen Container-Adapter zu schreiben, aber ich denke, du wärst viel besser dran, wenn du "von Null an schreibst, aber vielleicht intern einen Standard-Container verwendest". Zumal das 'Container'-Konzept tatsächlich * unmöglich ist * atomar zu machen, es sei denn, ihr' value_type' ist ein spezielles Objekt, das mit dem Container kooperiert, um sich atomar zu verhalten (zB wie könnte 'C [i] = x;' eine atomare Operation?). – Hurkyl