c++ - 简单的线程/互斥测试应用程序崩溃

标签 c++ multithreading c++11 mutex mingw-w64

我编写了一个简单的测试程序,它使用多个线程将随机样本累积到缓冲区中。每个线程都使用一个堆栈来减少互斥等待。 这是为了调查更大程序中的问题。

代码目前在 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;
}

最佳答案

workers.clear(); 不会加入所有线程。调用 clear() 将调用线程的解构函数。 std::thread::~thread会调用std::terminate()如果线程是 joinable() .由于您在创建 vector 后立即在 vector 上调用 clear(),因此线程仍在处理并且可以连接。

您必须在删除之前手动加入所有线程:

int main()
{
    // […]

    //This will join the threads
    for (std::thread& thread : workers)
    {
        thread.join();
    }
    workers.clear();

    return 0;
}

关于c++ - 简单的线程/互斥测试应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30873768/

相关文章:

c++ - 将整数舍入为浮点型并向 0 舍入

c++ - 替代可在 64 位 Linux 上运行的 googleperf 工具

c - 使 2 个循环并行运行

java - 使用匿名可运行类代码进入死锁状态,但使用 lambda 可以正常工作

c++ - 如何从成对的初始化列表构造对象?

c++ - 编译 cpp 文件时出错 (ros)

c++ - Boost Graph 作为简单 DAG Graph 的基础?

multithreading - sidekiq什么时候结束进程,从而释放内存?

c++ - 为什么调用函数后会陷入死循环?

c++ - 为什么没有为语句 "A x(A())"调用 A 的构造函数?