Я работаю над потоками, но прежде чем использовать потоки, я должен написать 2 программы.
У меня проблемы с пониманием вопросов, это кажется таким простым, но все же я не могу разобраться в этом. Я должен написать программы, основанные на вышеупомянутых двух вопросах, прежде чем я начну создавать программу, которая позволит выполнять обработку в одном или нескольких потоках. Каждый поток должен получить доступ к разному набору строк массива.
Для первого вопроса код, который я написал до сих пор:
#include <iostream>
#include <stdio.h>
int main()
{
int array [20][20];
int i, j;
/* output each array element's value */
for ( i = 0; i < 20; i++ )
{
for ( j = 0; j < 20; j++ )
{
printf("a[%d][%d] = %d\n", i,j, array[i][j] );
}
}
system ("PAUSE");
return 0;
}
Я хочу знать, является ли вышеуказанная программа последовательной? Я запустил программу, и она получила доступ ко всему массиву и выполнила одну задачу — распечатать все данные в массивах.
Я исследовал в режиме онлайн, что это означает под последовательной программой, и обнаружил, что это означает следующее утверждение: выполнить задачу a перед задачей b, но не одновременно. Это правильно?
Для второй части я сделал следующее:
#include <iostream>
#include <stdio.h>
void print_array(int array[20][20]);
int main()
{
int array [20][20];
int i, j;
print_array(array);
system ("PAUSE");
return 0;
}
// Output data in an array
void print_array(int array)
{
int i, j;
for ( i = 0; i < 20; i++ )
{
for ( j = 0; j < 20; j++ )
{
printf("a[%d][%d] = %d\n", i,j, array[i][j] );
}
}
}
Я иду в правильном направлении? Так же я получил возможность написать версию программы, которая позволит выполнять обработку в одном или нескольких потоках.
РЕДАКТИРОВАТЬ: я должен использовать 2D-массивы, извините, это не было ясно выше
Я не думаю, что вы идете в правильном направлении, но вы не далеко. Инструкции запрашивают некоторые предварительные шаги, необходимые для последовательной обработки массива и его параллельной работы. При написании параллельной программы часто полезно начинать с работающей последовательной программы и постепенно преобразовывать ее в параллельную программу. Следуя инструкциям, это способ сделать это.
Давайте рассмотрим части вопроса отдельно:
Простая задача, которую вы выбрали для своего массива, состоит в том, чтобы напечатать содержимое, но это не подходящая задача, потому что она не имеет никакого функционального результата. Более подходящей задачей будет сумма элементов в массиве. Другими задачами могут быть подсчет элементов, которые удовлетворяют некоторому условию, или умножение каждого элемента на два.
Итак, сначала попробуйте изменить исходную программу, чтобы суммировать элементы, а не печатать их.
(В вашем коде вы используете двумерный массив. Я бы посоветовал использовать одномерный массив для простоты.)
В этой части вы пытаетесь разбить функциональность на небольшие части. (В конце концов вы отправите эти единицы работы потокам для обработки, но сейчас вы просто делаете предварительные шаги.) Если мы сделали сумму в части 1, то здесь вы могли бы написать функцию, которая int sumKitems(int *array, int startIndex, int numItems)
, Основная программа затем вызывала бы это для каждого набора (скажем) 10 элементов в массиве и объединяла полные результаты, суммируя результаты каждого sumKitems
вызов.
Итак, если в массиве 100 элементов, вы можете сделать 10 вызовов sumKitems(...)
, сообщая функции для обработки 0 … 9, 10 … 19, …, 90 … 99. Это было бы вместо того, чтобы делать сумму по всем 100 пунктам индивидуально.
—
Подводя итог, можно сказать, что первая часть была бы простым циклом for, не слишком отличающимся от того, что вы написали, просто с некоторыми выполняемыми вычислениями.
Вторая часть должна делать точно такие же вычисления и возвращать точно такой же результат, просто используя другой вызов функции, который обрабатывает k
предметы в срок. (Если вы передадите количество элементов для обработки за один раз в качестве параметра, вы сможете сбалансировать стоимость связи с работой, выполняемой при переходе к многопоточному внедрению.)
В конце концов, вас, вероятно, попросят заменить звонок на sumKitems(...)
с очередью, которая отправляет работу потокам для самостоятельного выполнения.
Я считаю, что если вы не создаете отдельные потоки каким-либо образом, то на самом деле вы пишете последовательную программу. В вашем коде нет той части, где вы переходите в новый поток для выполнения какой-либо операции, в то время как основной поток выполняет что-то еще.
Резюме: ваш код выполняется в одном потоке — он последовательный
Вы должны передать массив не как целое число, а как двойной указатель -> int array[][]
или же int** array
Последовательное выполнение операций над массивом означает запуск с первого места в массиве и постепенное увеличение массива по мере выполнения операций.
array[10] = {0,1,2,3,4,5,6,7,8,9}
iterate through array with some action such as adding +5
array [10] = {5,6....}
Чтобы сделать это многопоточным, вам нужно, чтобы разные потоки работали в разных сегментах массива, например, в местах 0-4,5-9, и выполняли действие, чтобы оно могло быть выполнено за меньшее время. Если вы делаете это таким образом, вам не нужно беспокоиться о мьютексах.
Таким образом, поток один увеличивается через массив [10] {0,1,2,3}
Поток два приращения через массив [10] {4,5,6,7}
Каждое приращение по одному месту за раз, и оба потока работают одновременно