所以我有一个可以使用以下变量的函数。
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;
}