[英]does std::map::end() return different results from different threads?
I've got this thread pool that holds a container of objects, and whenever it receives a new piece of data, it updates all the objects with the same new piece of data.我有这个线程池,它包含一个对象容器,每当它收到一条新数据时,它就会用相同的新数据更新所有对象。 The work is preallocated on the construction of the thread pool, and this work is stored in the following data member
工作是在线程池的构建上预分配的,这个工作存储在下面的数据成员中
std::map<std::thread::id, std::vector<unsigned>> m_work_schedule
So if a thread's element in this map
has the elements 1,2 and 3 in its vector<unsigned>
, that means it is responsible for updating the objects with indexes 1,2 and 3 every time a new data point arrives.因此,如果此
map
中的线程元素在其vector<unsigned>
中包含元素 1,2 和 3,则意味着它负责在每次新数据点到达时更新索引为 1,2 和 3 的对象。
If I have ten objects and three threads, the work schedule might look something like this如果我有十个对象和三个线程,工作计划可能看起来像这样
140314357151488... 2, 5, 8,
140314365544192... 1, 4, 7,
140314373936896... 0, 3, 6, 9,
In every worker thread , it does some calculation and then adds its calculation to the shared aggregate variable.在每个工作线程中,它都会进行一些计算,然后将其计算添加到共享聚合变量中。 I'm confused though, because once all the threads are finished, only the final thread is supposed to put the finishing touches on the calculation.
不过我很困惑,因为一旦所有线程都完成,只有最后一个线程应该对计算进行最后的润色。 For some reason, this block is occasionally executing twice:
由于某种原因,这个块偶尔会执行两次:
if( std::prev(m_work_schedule.end())->first == std::this_thread::get_id() ){
std::cout << "about to finalize from thread " << std::this_thread::get_id() << ", which supposedly is equal to " << (--m_work_schedule.end())->first << "\n";
m_working_agg = m_final_f(m_working_agg);
m_out.set_value(m_working_agg);
}
The output looks like this: output 看起来像这样:
139680503645952... 2, 5, 8,
139680512038656... 1, 4, 7,
139680520431360... 0, 3, 6, 9,
about to finalize from thread 139680520431360, which supposedly is equal to 139680520431360
................
about to finalize from thread 139680503645952, which supposedly is equal to 139680503645952
terminate called after throwing an instance of 'std::future_error'
what(): std::future_error: Promise already satisfied
How can this block of code run twice, though?但是,这段代码怎么能运行两次呢? I am only reading from
m_work_schedule
, but the occasional nature of this suggests it's some sort of race condition.我只是在阅读
m_work_schedule
,但这种情况的偶尔性质表明这是某种竞争条件。 I'm struggling to think of any possible explanation for this, though.不过,我正在努力想出任何可能的解释。
std::map::end()
return different things in different threads? std::map::end()
在不同的线程中返回不同的东西吗?std::map::end()
affect another thread's?**std::map::end()
的读取是否会影响另一个线程的读取?** I bet your problem is here我打赌你的问题就在这里
for(unsigned i=0; i< m_num_threads; ++i) {
m_threads.push_back( std::thread(&split_data_thread_pool::worker_thread, this));
most_recent_id = m_threads.back().get_id();
m_work_schedule.insert(std::pair<std::thread::id, std::vector<unsigned> >(most_recent_id, std::vector<unsigned>{}));
m_has_new_dyn_input.insert(std::pair<std::thread::id, bool>(most_recent_id, false));
}
you are starting the threads while you are still populating the m_work_schedule_map.您在填充 m_work_schedule_map 时启动线程。 And as far as I can see there is no lock.
据我所知,没有锁。 So you have simultaneous readers and writers
所以你有同时的读者和作家
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.