因此,我正在尝试制作一个简单的多线程程序来验证 Collatz 猜想的大量数字并返回已验证数字的总数。每个线程(总共 4 个)执行一个数字间隔,并在数字达到 1 时更新“已验证”变量。我也在计时整个过程(与单线程计算进行比较)
我遇到的问题是,当我在程序结束时打印出“已验证”的 int 时,从来没有任何一致性,所以我猜要么线程正在相互写入,要么主线程之前完成其他人,因此打印一个不完整的数字。我还假设如果主线程在其他线程之前完成,clock() 计算也将关闭。那么,如何停止主线程继续运行,直到其他线程完成(从而使其等待更新的验证计数并完成准确的时间测量)?这就是我认为 WaitForSingleObject 所做的,但我猜它只是停止主线程退出,仍然允许它计算它的其他函数。
这是我第一次尝试任何多线程,我认为我不太了解同步和 WaitForSingleObject 命令的工作原理。到目前为止,这是我的主要功能中的内容:
编辑:这是我更新的 Main 函数和 Collatz 函数。我对其进行了修改,以便每个线程都访问一个单独的变量以避免同步问题,但问题仍然存在。当我打印出“已验证”时,没有一致的值 *
再次编辑:好的,所以我删除了每个 Mladen Janković 的“线程”int,并使用一个简单的计数器将不同的间隔分配给创建的线程。“已验证”现在有一个一致、正确的值。但是,当有 1,000,000 个数字时,我仍然无法让程序真正完成。测试它 100,000 甚至 10,000 可以完美地工作,但是当我将它增加到 1,000,000 个数字时,程序会无限期地运行(小时)而没有实际返回值。我猜它会卡在一个特定的值上(例如 Martin James 指出的 750831)。我尝试用 int 代替 long int,但似乎仍然存在溢出问题。有什么建议么?并感谢您的巨大帮助。
最后编辑:好的,所以我只是使用 long long 而不是 int,现在程序可以完美运行。感谢大家的帮助!
void main()
{
clock_t start;
clock_t finish;
unsigned int thread = 0;
start = clock();
HANDLE h1 = (HANDLE)_beginthreadex(NULL, 0, collatz_thread, NULL, 0, NULL);
HANDLE h2 = (HANDLE)_beginthreadex(NULL, 0, collatz_thread, NULL, 0, NULL);
HANDLE h3 = (HANDLE)_beginthreadex(NULL, 0, collatz_thread, NULL, 0, NULL);
for (int i = 750001 ; i <= 1000000 ; i++) { collatz(i, 4); }
WaitForSingleObject( h1, INFINITE );
WaitForSingleObject( h2, INFINITE );
WaitForSingleObject( h3, INFINITE );
finish = clock() - start;
double time = finish / (double) CLOCKS_PER_SEC;
validated = v1 + v2 + v3 + v4;
cout << validated << " numbers validated." << endl;
cout << endl << time << " seconds." << endl;
}
unsigned _stdcall collatz_thread (void* n)
{
selection++; // selects a different interval each time collatz_thread is called
switch (selection) {
case 1:
for (int i = 1 ; i <= 250000; i++) { collatz(i, 1); }
break;
case 2:
for (int i = 250001 ; i <= 500000; i++) { collatz(i, 2); }
break;
case 3:
for (int i = 500001 ; i <= 750000; i++) { collatz(i, 3); }
break;
}
return 0;
}
int collatz (int n, int thread)
{
int original = n;
while (n != 1) {
if (n%2 == 0)
n = (n/2);
else
n = (3*n + 1);
}
if (n == 1) {
switch (thread) {
case 1:
v1++;
break;
case 2:
v2++;
break;
case 3:
v3++;
break;
case 4:
v4++;
break;
}
return n;
}
}