std::map::end() 是否从不同线程返回不同的结果?
我有这个 线程池保存一个对象容器,每当它收到一个新对象时数据块,它用相同的新数据块更新所有对象。工作是在线程池的构造中预先分配的,并且该工作存储在以下数据成员中
std::map<std::thread::id, std::vector<unsigned>> m_work_schedule
因此,如果此 map
中的线程元素在其 中具有元素 1,2 和 3 Vector
,这意味着每次新数据点到达时,它负责更新索引为 1,2 和 3 的对象。
如果我有十个对象和三个线程,工作时间表可能看起来像这样
140314357151488... 2, 5, 8,
140314365544192... 1, 4, 7,
140314373936896... 0, 3, 6, 9,
在每个 工作人员thread,它会进行一些计算,然后将其计算添加到共享聚合变量中。不过我很困惑,因为一旦所有线程都完成后,只有最后一个线程应该对计算进行最后的处理。出于某种原因,这个块偶尔 执行两次:
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);
}
输出如下所示:
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
这段代码如何运行两次? 我只从 m_work_schedule
中读取,但这种情况的偶然性表明它是某种竞争条件。不过,我正在努力思考对此的任何可能的解释。
std::map::end()
是否在不同线程中返回不同的内容?- 一个线程使用
std::map::end()
进行读取会影响另一个线程的读取吗?** - 如果最后一个线程在所有线程完成工作之前完成,它是否可以再次随机进入该代码块?
- 线程ID可以改变吗?
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.
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:
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. I'm struggling to think of any possible explanation for this, though.
- Does a
std::map::end()
return different things in different threads? - Does one thread's reading with
std::map::end()
affect another thread's?** - If the last thread finalizes before all threads are finished working, can it randomly enter this block of code again?
- Can thread ids change?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我敢打赌您的问题是
在您仍在填充 m_work_schedule_map 的同时启动线程。据我所知,没有锁。所以你有同时的读者和作者
I bet your problem is here
you are starting the threads while you are still populating the m_work_schedule_map. And as far as I can see there is no lock. So you have simultaneous readers and writers