c ++ thread_local static std :: vector<> _M_start = NULL

时间:2015-04-16 01:52:28

标签: c++ multithreading c++11 vector stl

所以我有一个可以使用以下变量的函数。

std::vector<std::vector<indexValue>> asnGeoLists(delegationIndex.size());

在向量上的std :: sort期间,操作符&lt;()调用该函数。我多线程排序,功能继续正常工作。

我将变量更改为thread_local static,以避免每次调用函数并且程序崩溃时分配外部向量的开销。调试显示以下内容

#0  0x000000010000257d in std::vector<unsigned int, std::allocator<unsigned int> >::~vector (this=0x0) at stl_vector.h:425

我跟着堆栈发现它是从

中调用的
#5  0x000000010002f4ab in std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::~vector (this=0x109b78f28)

并且能够验证这是上述类型(并且没有其他类型)。我进入了这个框架,发现了

$5 = ('std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >' * const) 0x109b78f28
(gdb) print *this
$6 = {
  <std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >> = {
_M_impl = {
  <allocator<std::vector<unsigned int, std::allocator<unsigned int> > >> = {
    <__gnu_cxx::new_allocator<std::vector<unsigned int, std::allocator<unsigned int> > >> = {<No data fields>}, <No data fields>}, 
  members of std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::_Vector_impl: 
  _M_start = 0x0, 
  _M_finish = 0x109b70003, 
  _M_end_of_storage = 0x109b7a178
}
  }, <No data fields>}

所以_M_start = NULL。我的第一个猜测是有些东西是免费的两次,但我写了一些测试代码并对其进行了调试,似乎在删除了一个向量后的测试代码中,_M_start仍然具有旧值。我还验证了在某些示例代码中_M_start是指向第一个元素的指针。

在函数结束之前,我将指针转储到外部向量和向量的第一个元素,两者都不是NULL。

那么在函数的最后一个退出之后但是在pthread_exit()清理之前调用析构函数之前,如何将_M_start设置为NULL? (或者我在这里完全错过了其他的东西?)

编辑:我正在使用 bash-3.2 $ g ++ - mp-4.9 -v 使用内置规格。 COLLECT_GCC =克++ - MP-4.9 COLLECT_LTO_WRAPPER = /选择/本地/ libexec目录/ GCC / x86_64的 - 苹果darwin14 / 4.9.2 / LTO-包装 目标:x86_64-apple-darwin14 配置为:/opt/local/var/macports/build/_opt_mports_dports_lang_gcc49/gcc49/work/gcc-4.9.2/configure --prefix = / opt / local --build = x86_64-apple-darwin14 --enable-languages = c,c ++,objc,obj-c ++,lto,fortran,java --libdir = / opt / local / lib / gcc49 --includedir = / opt / local / include / gcc49 --infodir = / opt / local / share / info --mandir = / opt / local / share / man --datarootdir = / opt / local / share / gcc-4.9 --with-local-prefix = / opt / local --with-system-zlib --disable- nls --program-suffix = -mp-4.9 --with-gxx-include-dir = / opt / local / include / gcc49 / c ++ / --with-gmp = / opt / local --with-mpfr = / opt / local --with-mpc = / opt / local --with-isl = / opt / local --disable-isl-version-check --with-cloog = / opt / local --disable-cloog-version-check --enable-stage1-checking --disable-multilib --enable -lto --enable-libstdcxx-time --with-as = / opt / local / bin / as --with-ld = / opt / local / bin / ld --with-ar = / opt / local / bin / ar --with-bugurl = https://trac.macports.org/newticket --with-pkgversion =&#39; MacPorts gcc49 4.9.2_1&#39; 线程模型:posix gcc版本4.9.2(MacPorts gcc49 4.9.2_1) bash-3.2 $

以下代码似乎会触发问题,但偶尔会发生。

threadSort()的最后一个参数是要使用的线程数。从sortable :: score()中删除thread_local静态似乎不会触发问题。

#include <algorithm>
#include <iostream>
#include <thread>
#include <vector>

template<typename T>
void printVector(typename std::vector<T>::iterator& begin, typename std::vector<T>::iterator& end) 
{
    for(auto e = begin; e < end; e++) {
        std::cout << *e << ", ";
    }
    std::cout << std::endl;
}

template<typename T>
void threadSort(typename std::vector<T>::iterator begin, typename std::vector<T>::iterator end, unsigned int t)
{
    unsigned int                threadLength, i;

    if(end - begin < 2*t || t == 1) {
        std::sort(begin, end);
        return;
    }
    threadLength = (end - begin) / t;
    std::thread threads[t];
    for(i=0; i< t-1; i++) {
        threads[i] = std::thread(std::sort<typename std::vector<T>::iterator>, begin + i*threadLength, begin + (i+1)*threadLength);
    }
    threads[i] = std::thread(std::sort<typename std::vector<T>::iterator>, begin + i*threadLength, end);
    for(i=0; i < t; i++) {
        threads[i].join();
    }

    for(i=0; i<t-2; i++) {
        std::inplace_merge(begin, begin + (i+1)*threadLength, begin + (i+2)*threadLength);
    }
    std::inplace_merge(begin, begin + (i+1)*threadLength, end);
    return;
}

class sortable {
    public:
        bool operator<(const sortable& r) const { return this->score() < r.score(); }
        int_fast64_t score() const {
            static thread_local std::vector<std::vector<unsigned int>>      vvi(21);

            for(unsigned int i; i < vvi.size(); i++) {
                vvi[i].push_back(7);
                vvi[i].push_back(9);
            }
            for(unsigned int i = 0; i < vvi.size(); i++) {
                vvi[i].resize(0);
            }
            return 8;
        }

};

int main(int argc, char *argv[])
{
    std::vector<sortable>   foo(500);
    threadSort<sortable>(foo.begin(), foo.end(), 8);
    return 0;
}

0 个答案:

没有答案