multithreading - 在多线程世界中使用带有shared_ptr向量的std::sort的危险

标签 multithreading sorting c++11 boost vector

这是我将应用程序升级到多线程世界时遇到的简化版本(C++ 11)。本质上,我有shared_ptr的向量,并且正在对其执行std::sort。我可以理解,当多个线程尝试对它进行排序时,它很危险,因为在第一次排序时,迭代器可能不得不四处移动。但是,在这里,我已经有一个排序的向量。现在调用std::sort不会造成任何麻烦(这就是我认为什么都不需要移动的麻烦),但是它会随机崩溃(现在为什么我在一个已排序的容器上实际上调用了std::sort呢?代码中,数据是未排序的,但这与最终结果无关紧要)。这是示例代码

#include <iostream>
#include <thread>
#include <vector>
#include <boost/shared_ptr.hpp>  
const int MAX = 4;
#define LOOP_COUNT 200

struct Container {
    int priority;
    Container(int priority_)
        : priority( priority_)
    {} 
};

struct StrategySorter {
    int operator()( const boost::shared_ptr<Container>& v1_,
        const boost::shared_ptr<Container>& v2_ )
    {
      return v1_->priority > v2_->priority;    
    } 
 };

std::vector<boost::shared_ptr<Container>> _creators;

void func() {    
    for(int i=0; i < LOOP_COUNT; ++i)    {
      std::sort( _creators.begin(), _creators.end(),  StrategySorter() );
    } 
}
int main()
{

   int priority[] = {100, 245, 312, 423, 597, 656, 732 };
   size_t size = sizeof(priority)/sizeof(int);

   for(int i=0; i < size; ++i)
   {
      _creators.push_back(boost::shared_ptr<Container>(new Container(priority[i])));
   }

   std::thread t[MAX];
   for(int i=0;i < MAX; i++)
   {
      t[i] = std::thread(func);
   }

   for(int i=0;i < MAX; i++)
   {
      t[i].join();
   }
}

错误 :
../boost_1_56_0/include/boost/smart_ptr/shared_ptr.hpp:648:类型名称boost::detail::sp_member_access::type boost::shared_ptr::operator->()const [with T = Container;类型名boost::detail::sp_member_access::type = Container *]:断言“px!= 0”失败。

具有原始指针不会使它崩溃,因此它特定于shared_ptr。
用互斥保护std::sort可以防止崩溃。
我不明白为什么这种情况会导致行为不一致。

最佳答案

不能保证最终不会移动的元素不会写入。

它可能想要移动轴心,在中间阶段向后排序一些东西,甚至在没有自我检查优化的情况下甚至调用swap(a,a)(因为检查可能比交换更昂贵)。

无论如何,如果它什么都不做的操作就是UB,那将是一个可怕的操作。

如果不采取任何措施,这是一种保证不采取任何措施的方法:

template<class C, class Cmp>
void my_sort( C& c, Cmp cmp ) {
  using std::begin; using std::end;
  if (std::is_sorted( begin(c), end(c), cmp ))
    return;
  std::sort( begin(c), end(c), cmp );
}

但是我不会用

关于multithreading - 在多线程世界中使用带有shared_ptr向量的std::sort的危险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34289604/

相关文章:

c - WinAPI中如何让两个线程共享一个全局变量?

c++ - 在无限循环中调用 Sleep() 有多重要?

node.js - 在管理器/ worker 模式中使用子进程以确保线程安全时,Node.js 中是否需要锁定?

c# - 按升序或降序对数字或字母进行通用排序

c++ - 在自定义类中实例化自定义类时出现 "expected type-specifier"错误

c++ - MinGW 错误 : ‘thread’ is not a member of ‘std’

python - 按键对字典项目进行排序,超越字母数字排序

php - MySQL 查询 - 如何以某种方式对结果进行排序

c++ - 什么时候应该在 C++11 中使用 constexpr 功能?

c++ - 铛+ libc++ : combination of make_tuple with make_shared leads to early object destruction