C++ 正在尝试实现线程池,但正在调用中止
我试图实现一个线程池,一个生产者、几个消费者和我的线程在任何事情发生之前不断地调用中止异常 为了实现这一点,我使用了一个互斥锁,该互斥锁与一个condition_变量配对,用于让线程等待主程序线程通知需要处理的内容。我正在visual studio 2015中使用c++11。我很确定它与等待机制有关,因为它在我实现它时才开始这样做,但我不知道如何修复它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
//...
#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等待不是应该解锁锁吗?