我编写了一个简单的测试程序,它使用多个线程将随机样本累积到缓冲区。每个线程使用一个堆栈来减少互斥锁等待。 这是为了在更大的计划中调查问题。
代码目前在mingw-w64 4.9.2
上崩溃知道为什么吗?
调试在不可用的地方停止“收到信号”(ntdll!DbgBreakPoint)
#include <iostream>
#include <vector>
#include <random>
#include <thread>
#include <mutex>
#include <cstdint>
//The function which will be run concurrently in several threads
void work(float * buf, uint64_t * ns, std::mutex * mtx)
{
std::mt19937 generator;
std::uniform_real_distribution<double> distrib(0., 1.);
std::vector<float> stack;
unsigned int stackPos = 0;
for(unsigned int i=0;i<1000000;i++)
{
//Generate a random sample uniformly between 0 and 1
double sample = distrib(generator);
//Append the sample to the stack
if(stackPos>=stack.size())
{
stack.resize(stackPos+1);
}
stack[stackPos] = sample;
++stackPos;
//Try to acquire the accumulation buffer
bool locked = mtx->try_lock();
//Force aquire if the stack is too large and if try_lock failed
if(!locked && stackPos>2000)
{
mtx->lock();
locked = true;
}
//If the buffer lock is aquired, flush the stack
if(locked)
{
for(unsigned int i=0;i<stackPos;i++)
{
*buf += stack[i];
*ns = *ns + 1;
}
stackPos = 0;
//And unlock
mtx->unlock();
}
}
}
int main()
{
float buffer = 0;
uint64_t numSamples = 0;
std::mutex mtx;
//Start a couple of parallel threads
std::vector<std::thread> workers;
for(unsigned int i=0;i<16;i++)
{
workers.emplace_back(std::thread(work, &buffer, &numSamples, &mtx));
}
//This will join the threads
workers.clear();
std::cout << "Average : " << buffer/numSamples << std::endl;
return 0;
}
答案 0 :(得分:4)
workers.clear();
不会加入所有线程。调用clear()
将调用线程的解构器。如果帖子为std::thread::~thread
,则std::terminate()
会调用joinable()
。由于您在创建向量后立即在向量上调用clear()
,因此线程仍在处理并且可以连接。
在删除之前,您必须手动加入所有线程:
int main()
{
// […]
//This will join the threads
for (std::thread& thread : workers)
{
thread.join();
}
workers.clear();
return 0;
}