对于大多数错误,我经常知道我需要朝哪个方向前进,但在这里我不知道。
所以让我们从断点本身开始:
使用线程库进行任何交互都是相对较少的,所有这些都是: 包含:
#include <thread>
用法:
void evolve(double* bestN, double* bestP, double* bestM, double* bestQ, double* bestWinConstant) {
std::thread threadArray[threadAmount];
for (int i = 0; i < 100000; i++) {
for (int t = 0; t < threadAmount; t++) {
if (gameArrayInUse[t] == 0) {
copyArray(gameArray[t], startArray);
gameArrayInUse[t] = 1;
threadArray[t] = std::thread(playGames, i, t);
std::cout << "------------New Thread Spawned, No: " << t << std::endl;
break;
}
if (t == threadAmount - 1) {
t = -1;
}
}
}
for (int i = 0; i < threadAmount; i++)
{
std::cout << "JOIN THREADS--------------------------------------------------" << std::endl;
threadArray[i].join();
}
}
在控制台中看到的错误(应该注意每次都会改变):
Start of evolution on magnitude:1
------------New Thread Spawned, No: 0Completed:
0.000000%
------------New Thread Spawned, No: 1
Compl
由于我对此缺乏了解,我很抱歉,如果您发现我提供的有关我的代码缺乏某些方面的内容,我会恳请您通过评论通知我,以便我可以对其进行修改。
答案 0 :(得分:7)
“断点”实际上由_STD terminate()
触发,上面一行。 (特别是在调试本机代码时,我发现看一下看起来无法解释时似乎导致错误的那一行是一种健康的习惯。)根据包裹它的情况,它会在你{{1}时被触发在正在运行的现有线程之上的线程。
C ++不允许您覆盖正在运行的线程对象。在运行move
循环的每次迭代之前,应确保在for(i)
循环中创建的每个线程都已终止。你可以致电thread::join
来做到这一点。或者,您可以调用thread::detach
让线程独立运行而不需要代表它的对象,但您无法检查其完成情况。
您还必须确保在函数返回之前已完成每个线程,否则在运行for(t)
对象被销毁时您将收到类似的错误。
答案 1 :(得分:0)
该代码看起来很可疑......
在你的内部循环中,你可以:
if (t == threadAmount - 1) {
t = -1;
}
因此,t
在下一次迭代时会小于threadAmount
,因此它会再次循环。但是在那时,gameArrayInUse[t]
是1
所以看起来你在浪费CPU做无用的东西。
假设仅从该线程修改变量,则这是真的。如果您从另一个线程修改它,那么因为您不使用任何同步原语(如mutex
),那么它是未定义的行为。
如果您不理解多线程,那么在编写代码之前找到一些好书(对于。例如C ++并发)并阅读它们。
我猜您的playGames
函数会修改变量gameArrayInUse[t]
。假设是这种情况,那么另一个问题是你开始的线程比你想象的多,因为你只是等待t
线程在最后加入。
另一件令人怀疑的事情是循环中的break
。鉴于您中断,您将在下一次迭代时尝试相同的t
,因为t将从0重新开始。
因此,似乎整个代码没有意义,并且假设它不完整且我们不知道你想要做什么 ...我们几乎只能说无论预期做什么,您的代码都会遇到很多问题。