C++ 正在尝试实现线程池,但正在调用中止

C++ 正在尝试实现线程池,但正在调用中止,c++,multithreading,c++11,threadpool,C++,Multithreading,C++11,Threadpool,我试图实现一个线程池,一个生产者、几个消费者和我的线程在任何事情发生之前不断地调用中止异常 为了实现这一点,我使用了一个互斥锁,该互斥锁与一个condition_变量配对,用于让线程等待主程序线程通知需要处理的内容。我正在visual studio 2015中使用c++11。我很确定它与等待机制有关,因为它在我实现它时才开始这样做,但我不知道如何修复它 //... #define NUMBER_THREADS 8 //should be above 0 std::mutex nodelista

我试图实现一个线程池,一个生产者、几个消费者和我的线程在任何事情发生之前不断地调用中止异常

为了实现这一点,我使用了一个互斥锁,该互斥锁与一个condition_变量配对,用于让线程等待主程序线程通知需要处理的内容。我正在visual studio 2015中使用c++11。我很确定它与等待机制有关,因为它在我实现它时才开始这样做,但我不知道如何修复它

//...

#define NUMBER_THREADS 8 //should be above 0
std::mutex nodelistaccessmutex;
std::condition_variable worktobedone;

//...

int main(int argc, char* argv[])
{


    //...

    //create threads for USE_LIST_THREAD and NUMBER_THREADS

    std::thread nodeForceCalculatorThreads[NUMBER_THREADS];
    std::stack<Node*> nodeStack;
    if (USE_LIST_THREAD) {
        for (int i = 0; i < NUMBER_THREADS; i++) {
            nodeForceCalculatorThreads[i] = std::thread(threadPool, nodeStack);
        }
    }
    for(int i = 60; i > 0; i--){
        OrderedZListForceCalculationWithThreads(node_list, current - previous, nodeStack);
    }

    std::cout << "done" << current - begin << std::endl;

    if (USE_LIST_THREAD) {
        for (int i = 0; i < NUMBER_THREADS; i++) {
            nodeForceCalculatorThreads[i].join();
        }
    }
    getchar();
    return 0;
}

//...


//function that I think is causing the problem:

void threadPool(std::stack<Node*> nodeStack) {
    std::unique_lock<std::mutex> lk(nodelistaccessmutex);
    while (true) {
        nodelistaccessmutex.lock(); //lock or lock guard? notify one or all

        worktobedone.wait(lk, [nodeStack] {return nodeStack.empty();});
        std::cout << ".";

        //do actual work here
        //nodelistaccessmutex.unlock();

    }
    return;
}

//...

void OrderedZListForceCalculationWithThreads(std::list<Node*> node_list, double i_interval, std::stack<Node*> nodeStack) {
    //std::cout << ".";
    double x, y, z, x1, y1, z1, x2, y2, z2, distance, force;

    if (i_interval <= 0) {
        return;
    }

    for (auto& node_i : node_list) {
        nodeStack.push(node_i);
        worktobedone.notify_all();
    }
}
/。。。
#定义线程数\u 8//应大于0
std::mutex nodelistacessmutex;
std::条件_变量worktobedone;
//...
int main(int argc,char*argv[])
{
//...
//创建线程以供使用\u列出\u线程和编号\u线程
线程节点forceCalculatorThreads[线程数];
std::堆栈节点堆栈;
如果(使用列表线程){
对于(int i=0;i0;i--){
OrderedZListForceCalculationWithThreads(节点列表,当前-上一个,节点堆栈);
}

std::我能不能发现,如果我注释掉nodelistaccessmutex.lock();它会运行,尽管我非常确定它需要在“否”之前锁定?这两个(内部循环锁定和解锁)都不需要在发布的代码中。
.wait(…)
解锁进入等待的互斥锁,在退出等待时重新获取互斥锁。如果有工作要同时完成,您可以在获取后解锁
lk
,然后重新锁定
lk
,然后转到下一个while迭代。一旦将
nodelistaccesmutex
切换到
lk
,则,您不应该再直接触摸它。我还质疑该节点堆栈是否应该是一个值参数。它看起来确实应该是一个引用。注释掉
unlock
后,您的线程将永远保持互斥锁。此外,您的计算线程修改
nodeStack
,而不保持保护的互斥锁就是它。修复这两件事,让池中的线程从堆栈中弹出一些东西,它应该会工作。这就修复了它@WhozCraig谢谢!(是的,我将它改为引用)@DavidSchwartz等待不是应该解锁锁吗?