Итак, я пытаюсь создать простую многопоточную программу, которая проверяет гипотезу Collatz для большого набора чисел и возвращает общее количество проверенных номеров. Каждый поток (всего 4) выполняет интервал чисел и обновляет «проверенную» переменную, когда число достигает 1. Я также определяю весь процесс (для сравнения с одним потоковым вычислением)Простая многопоточная помощь? C++, WaitForSingleObject и синхронизация
Проблема, что никогда не бывает согласованности, когда я печатаю «проверенный» int в конце программы, поэтому я предполагаю, что ни потоки пишут друг над другом, либо основной поток заканчивается перед другими, тем самым печатая неполное число. Я также предполагаю, что вычисления clock() также будут выключены, если основной поток завершится перед другими. Итак, как мне остановить главный поток от продолжения до тех пор, пока другие потоки не будут завершены (что заставило бы ждать обновления проверенного счета и завершения точного измерения времени)? Это то, что я думал WaitForSingleObject, но я предполагаю, что он просто останавливает основной поток от EXITING, все еще позволяя ему вычислять другие его функции.
Это мой первый переход на любую многопоточность, и я не думаю, что я вполне понимаю работу синхронизации и команду WaitForSingleObject. Вот что у меня есть до сих пор в моей основной функции:
EDIT: Вот моя обновленная функция Main и функция Collatz. Я изменил его так, чтобы каждый поток обращался к отдельной переменной, чтобы избежать проблемы синхронизации, но проблема все еще сохраняется. Там нет никакого последовательного значения, когда я распечатать «подтверждено» *
EDIT СНОВА: Хорошо, так что я удалил «нить» ИНТ на Младен Янкович, а просто использовал простой счетчик, чтобы распределить различные интервалы созданные потоки. В настоящее время существует согласованное, правильное значение для «проверенных». ОДНАКО, я до сих пор не могу заставить программу фактически закончить, когда есть 1 000 000 номеров. Тестирование его на 100 000 или даже 10000 работает безупречно, но когда я до него до 1 000 000 номеров, программа работает неопределенно (часы) без фактического возврата значений. Я предполагаю, что он застревает в определенном значении (например, 750831, как указал Мартин Джеймс). Я попытался заменить int на long int, но кажется, что он все еще страдает от переполнения. Какие-либо предложения? И спасибо за огромную помощь.
ПОСЛЕДНИЙ EDIT: Хорошо, так что я просто использовал долго долго вместо междунар и теперь программа работает безупречно. Спасибо всем за помощь!
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;
}
}
См. Мой обновленный ответ и укажите код для функции collatz_thread. –
Хорошо, туда вы идете. Я также обновил сообщение с дополнительной информацией о моей текущей проблеме. – Vance