简单 thread/mutex 测试应用程序崩溃
Simple thread/mutex test application is crashing
我写了一个简单的测试程序,它使用多线程将随机样本累积到缓冲区。每个线程都使用一个堆栈来减少互斥等待。
这是为了调查更大程序中的问题。
代码目前在 mingw-w64 4.9.2 上崩溃
知道为什么吗?
调试在 "signal-received" 处停止在一个不可用的地方 (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;
}
workers.clear();
不会加入所有线程。调用 clear()
将调用线程的析构函数。 std::thread::~thread
will call std::terminate()
if the thread is joinable()
。由于您在创建向量后立即在向量上调用 clear()
,因此线程仍在处理并且可以连接。
您必须在删除之前手动加入所有线程:
int main()
{
// […]
//This will join the threads
for (std::thread& thread : workers)
{
thread.join();
}
workers.clear();
return 0;
}
我写了一个简单的测试程序,它使用多线程将随机样本累积到缓冲区。每个线程都使用一个堆栈来减少互斥等待。 这是为了调查更大程序中的问题。
代码目前在 mingw-w64 4.9.2 上崩溃
知道为什么吗?
调试在 "signal-received" 处停止在一个不可用的地方 (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;
}
workers.clear();
不会加入所有线程。调用 clear()
将调用线程的析构函数。 std::thread::~thread
will call std::terminate()
if the thread is joinable()
。由于您在创建向量后立即在向量上调用 clear()
,因此线程仍在处理并且可以连接。
您必须在删除之前手动加入所有线程:
int main()
{
// […]
//This will join the threads
for (std::thread& thread : workers)
{
thread.join();
}
workers.clear();
return 0;
}