concurrent_vector 无效数据

234*_*40C 3 c++ concurrency multithreading visual-c++ concurrent-vector

使用:VC++ 2013

concurrency::concurrent_vector<datanode*> dtnodelst
Run Code Online (Sandbox Code Playgroud)

有时,当我这样做时dtnodelst->at(i).... 我收到一个无效地址 (0XCDCD.. ofc) 这不应该是我推回后的原因,我从不删除或删除任何它(即使我删除它应该已返回已删除的旧地址...但我从未删除,因此情况并非如此)

dtnodelst itm = new dtnodelst ();
....
dtnodelst->push_back(itm);
Run Code Online (Sandbox Code Playgroud)

关于可能发生什么的任何想法?

ps 我正在使用 Windows 线程池。有时.. 我可以做 800 万次插入和查找,一切顺利......但有时甚至 200 次插入和查找都会失败。我有点失落。任何帮助将不胜感激!

感谢和最好的问候

实际代码作为参考

ps 我是否遗漏了某些东西,或者使用正确的格式对过去的代码感到痛苦?我记得它之前是自动对齐的... -_-

struct datanode {       
     volatile int nodeval;
     T val;
};
concurrency::concurrent_vector<datanode*> lst
inline T find(UINT32 key)
{
    for (int i = 0; i < lst->size(); i++)
    {
       datanode* nd = lst->at(i);
       //nd is invalid sometimes
       if (nd)  
       if (nd->nodeval == key)
       {
         return (nd->val);
       }
    }
    return NULL;
}
inline T insert_nonunique(UINT32 key, T val){
   datanode* itm = new datanode();
   itm->val = val;
   itm->nodeval = key;
   lst->push_back(itm);
   _updated(lst);                       
   return val;
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ton 5

问题是使用concurrent_vector::size()which 不是完全线程安全的,因为您可以获得对尚未构造的元素(其中内存包含垃圾)的引用。Microsoft PPL 库(在concurrency::命名空间中提供它)使用 Intel TBB 实现concurrent_vector和 TBB Reference说:

size_type size() const| 返回: 向量中的元素数。结果可能包括通过并发调用任何增长方法已分配但仍在构建中的元素。

请参阅我的博客以获取更多解释和可能的解决方案。

在 TBB 中,最合理的解决方案是使用tbb::zero_allocatorof 作为底层分配器,concurrent_vector以便在 size() 也计算它之前用零填充新分配的内存。

concurrent_vector<datanode*, tbb::zero_allocator<datanode*> > lst;
Run Code Online (Sandbox Code Playgroud)

然后,条件if (nd)将过滤掉尚未准备好的元素。