c++ - 插入 int 集合时崩溃

标签 c++ multithreading segmentation-fault shared-ptr aerospike

我的程序在将 和 int 插入集合时似乎崩溃了,我无法找出原因。相关代码如下:

bool request::check_list(std::vector<int> search_vec)
{

    std::set<int> *tmp_ptr = create_int_set();
    boost::shared_ptr<std::set<int> > c_list(tmp_ptr);


    if(aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list) != AEROSPIKE_OK)
    {
        return false;
    }

    for(int i = 0; i < search_vec.size(); i++)
    {
        if(c_list->find(search_vec[i]) != c_list->end())
        {
            c_list_value_ = search_vec[i];
            return true;
        }
    }
    return false;       
}

bool request::process_set(const as_val *val, void * udata)
{
    try
    {
        boost::shared_ptr<std::set<int> > c_set = *(boost::shared_ptr<std::set<int> > *)(udata);
        if(val == NULL)
        {
            return true;
        }
        if(val->type == AS_REC)
        {
            if (val!=NULL)
            {
                as_record *rec = as_record_fromval(val);

                if (rec!=NULL)
                {
                    as_integer* c_id = as_record_get_integer(rec,"c_id");
                    int cid = 0;
                    cid = boost::lexical_cast<int>(c_id->value);
                    if(c_set != nullptr)
                    {
                        c_set->insert(c_id);
                    }
                    as_record_destroy(rec);
                    as_integer_destroy(c_id);
                }
        }
        return true;
    }catch(...){}
    return false;
}

c_set->insert(c_id); 导致了段错误。这是崩溃的回溯:

#0  0x00007f2064299f94 in std::_Rb_tree_rotate_right(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*&) () from /usr/lib64/libstdc++.so.6
#1  0x00007f206429a12b in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib64/libstdc++.so.6
#2  0x00000000004829d9 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_<int const&> (this=0x7f1fcc005440, __x=0x0, __p=0x7f1f3c0009a0, __v=@0x7f20159e729c)
    at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:981
#3  0x000000000047f1e0 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_unique<int const&> (this=0x7f1fcc005440, __v=@0x7f20159e729c)
    at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:1299
#4  0x000000000047c473 in std::set<int, std::less<int>, std::allocator<int> >::insert (this=0x7f1fcc005440, __x=@0x7f20159e729c)
    at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_set.h:415
#5  0x00000000004765ee in request::process_set (val=0x7f20159e73e0, udata=0x7f200b9d6620) at ../../request.cpp:1862

我假设存在集合未初始化的问题,或类似的问题。以下是我如何从另一个函数创建和传递该集合,我尝试了两种方法来创建它:

boost::shared_ptr<std::set<int> > c_list(new std::set<int>());

std::set<int> *tmp_ptr = create_int_set();
boost::shared_ptr<std::set<int> > c_list(tmp_ptr);

std::set<int>* request::create_int_set()
{
    return new std::set<int>();
}

调用函数是来自数据库驱动程序的回调函数,它接受一些不同的对象,但最值得注意的是 process_set 和 c_list,它们作为 void* 传递:

aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list)

这种崩溃并不总是发生,事实上,这种情况相当罕见,这让我觉得我做错了什么,某种未定义的行为。任何帮助将不胜感激!

最佳答案

aerospike APi documentation对于回调来说(即 process_set() ,此处):

Execute a query and call the callback function for each result item. Multiple threads will likely be calling the callback in parallel. Therefore, your callback implementation should be thread safe.

由于多个线程可能同时插入同一集合(共享指针指向的集合)中,因此您将遇到竞争条件,从而出现未定义的行为!

所以我认为你至少应该用 lock_guard 来保护你的设置插入 block 。在互斥锁上。

重要编辑: boost::shared_ptr<> can't assumed to be thread safe 。在 boost.org 上的示例中,他们建议共享指针超出范围可能会导致竞争。因此,强烈建议遵循 Matthew Moss 评论中的建议,并使用指向 process_set() 范围内的集合的原始指针。

关于c++ - 插入 int 集合时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32231888/

相关文章:

c++ - 没有 CUDA 代码的线程中的 CUDA 段错误

c - aio_write 和 memset 参数无效和段错误(核心已转储)

c++ - vector vector 的段错误

c - 访问合法内存地址时出现段错误

c++ - 如何使用 Xcode 在 C++ 库中使用 __IPHONE_4_0 定义?

c++ - 为什么不能为冒泡排序设置一个循环?

Python 线程似乎无缘无故停止/卡住/挂起?可能的原因?

c++ - 避免构造函数中 const 引用和右值引用的指数增长

c++ - 使用零长度元组 boost 异常,如何解决

javascript - Parallel.js 如何在 Javascript 中进行多线程编程?