简单 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;
}