そのため、多数の数値セットに対してコラッツ予想を検証し、検証された数値の合計を返す単純なマルチスレッド プログラムを作成しようとしています。各スレッド (合計 4) は数値のインターバルを実行し、数値が 1 に達すると「検証済み」変数を更新します。また、プロセス全体のタイミングを計っています (シングル スレッド計算と比較するため)。
私が抱えている問題は、プログラムの最後に「検証済み」の int を出力するときに一貫性がないことです。そのため、スレッドが互いに上書きしているか、メインスレッドが前に完了していると推測しています他のもの、したがって不完全な数値を出力します。また、メインスレッドが他のスレッドよりも先に完了する場合、clock() の計算もオフになると想定しています。では、他のスレッドが完了するまでメインスレッドが続行しないようにするにはどうすればよいでしょうか (したがって、更新された検証済みカウントを待機させ、正確な時間測定を完了するようにします)。これは私が WaitForSingleObject が行ったと思っていたことですが、メインスレッドの終了を停止し、他の関数を計算できるようにするだけだと思います。
マルチスレッドに取り組むのはこれが初めてで、同期と WaitForSingleObject コマンドの仕組みをよく理解していないと思います。主な機能でこれまでに持っているものは次のとおりです。
編集: これが私の更新された Main 関数と Collatz 関数です。同期の問題を回避するために各スレッドが個別の変数にアクセスするように変更しましたが、問題は解決しません。「検証済み」を出力すると一貫した値がありません*
もう一度編集: わかりましたので、Mladen Janković ごとに「スレッド」int を削除し、単純なカウンターを使用して、作成されたスレッドにさまざまな間隔を分散させました。「検証済み」の一貫した正しい値が存在するようになりました。ただし、1,000,000 の数字がある場合でも、プログラムを実際に終了させることはできません。100,000 または 10,000 のテストでも問題なく動作しますが、1,000,000 の数値まで上げると、プログラムは実際に値を返すことなく無期限 (時間) に実行されます。特定の値 (たとえば、Martin James が指摘した 750831) で動かなくなっていると推測しています。long int を int に置き換えてみましたが、それでもオーバーフローに悩まされているようです。助言がありますか?そして多大な助けをありがとう。
最終編集: よし、int の代わりに long long を使用したところ、プログラムは問題なく動作するようになりました。みんな助けてくれてありがとう!
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;
}
}