samedi 21 février 2015

Is c++11 "range-based for" thread-safe?

I have an environment modelled by lines and points packed in two std::vector. I want to calculate a field generated by this environnement. I multithreaded the process. As the environment is totally defined at the begining, threads should only read on it so I don't use any syncrhonisation as discribed here and there.


The problem comes now : when I iterate through the lines in the environement, I have two different behaviours depending if I use the c++11 range-based for statment or if I use a more common for statement with iterators. It seems that the range-based for isn't thread-safe and I'm wondering why?


If I'm not right assuming that, it might significate I have a more deep problem that may reappear latter.


Here is a piece of code, the first worker seems to work, the second provoke a segfault.



Worker::worker(Environement const* e, int id):threadId(id),env(e)
{
}

// worker that seems to do his job.
void Worker::run() const
{
cout<<"in thread n "<<_threadId<<endl;
vector<Line> const* lines = &env->_lines;

for(std::vector<Line>::const_iterator it = lines->begin() ;it != lines->end(); ++it ){
it->hello();
}
}

// create a segfault
void Worker::run2() const
{
cout<<"in thread n "<<_threadId<<endl;
vector<Line> const& lines = env->_lines;

for(auto it : lines){
it.hello();
}
}


The simplified structure of data if needed:



struct Line
{
void hello() const {std::cout<<"hello"<<std::endl;}
}

struct Environment
{
std::vector<Line> _lines;
std::vector<Point> _points;
}

Aucun commentaire:

Enregistrer un commentaire