Boost logo

Boost Users :

Subject: [Boost-users] [unordered] Are unordered containers thread safe?
From: Ralf Goertz (R_Goertz_at_[hidden])
Date: 2010-03-31 10:59:04


Hi,

are unordered containers thread safe, e.g. can I do something like

typedef boost::unordered_multimap<int, int> Map;
Map m;
std::vector<int> v;
bool needs_to_be_erased(int val); //heavy function telling me whether val is
                                  //needed in the map;

//fill m
//fill v uniquely with all keys in m;

int i;
#pragma omp parallel for // parallelize the loop
for (i=0;i<v.size();++i) {
        std::pair<Map::iterator,Map::iterator> r=m.equal_range(v[i]);
        for (Map::iterator mi=r.first;mi!=r.second;) {
                Map::iterator to_be_erased=m.end();
                if (needs_to_be_erased(mi->second)) {
                        to_be_erased=mi;
                }
                ++mi;
                if (to_be_erased!=m.end()) {
                        m.erase(to_be_erased);
                        to_be_erased=m.end();
                }
        }
}

The reason I ask is that every once in a while the program crashes
because of an assertion failure:

BOOST_ASSERT(b2 == buckets_end() || !b2->empty()); (line 1018)

in boost/unordered/detail/hash_table_impl.hpp function

void recompute_begin_bucket(bucket_ptr b1, bucket_ptr b2).

It seems as if erasing from m can cause problems even though it is
guaranteed that one and the same element is never tried to be erased by
different threads (they never "see" the same elements). Interestingly,
the assertion failure occurs in a function for which the comment says:

"This is called when a range has been erased"

but I never erase ranges.

Furthermore, using "schedule(dynamic)" in the omp pragma above almost
always leads to one or more threads not finishing.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net