I wrote a simple test program which accumulates random samples to a buffer using multiple threads. Each thread uses a stack for reducing the mutex waits. This is for investigating problems in a much larger program.
The code currently crashes on mingw-w64 4.9.2
Any idea why?
Debugging halts on "signal-received" in a non-usable place (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();
is not going to join all of the threads. Callingclear()
will call the threads' deconstructors.std::thread::~thread
will callstd::terminate()
if the thread isjoinable()
. Since you are callingclear()
on the vector right after you create the vector the threads are still processing and are joinable.You have to join all threads manually before deleting them: