Параллельные вычисления с помощью WinAPI

В этой статье поговорим о параллельных вычислениях, реализуемых средствами Windows API.

В контексте исполнения процесса могут выполняться несколько потоков. В операционной системе Windows поток – это единица исполнения, которой ОС выделяет процессорное время для выполнения программы.

Рассмотрим функций доступные в WIndows API для работы с потоками. Для того, чтобы создать поток используется функция CreateThread.

где:

  • lpSecAttr – указатель на SECURITY_ATTRIBUTES, этот параметр также можно указать равным NULL, тогда возвращаемый дескриптор не будет наследоваться
  • StackSize – начальный размер стека (указывается в байтах).  Если в качестве параметра указать ноль, то система задаст размер стека по умолчанию
  • lpStartFuncAddr – это указатель на функцию, которая будет исполняться потоком, таким образом здесь будет указан стартовый адрес потока; эта функция должна быть определена в программе следующим образом: DWORD WINAPI FunctionName(LPVOID)
  • p – это указатель на переменную, которую нам необходимо передать в функцию FunctionName(LPVOID p), исполняемую потоком
  • dwCreatParam – параметры, которые управляют созданием потока. Можно указать: 0 (тогда поток начнет исполняться сразу после его создания), CREATE_SUSPENDED (поток начнет исполняться, когда будет выполнена функция ResumeThread, о ней позже)
  • thrId – это указатель на переменную, в которую будет записан идентификатор потока

ExitThread – эта функция завершает поток, как видно из её определения ниже, она ничего не возвращает. Поток может завершиться при вызове этой функции или при возврате из функции DWORD WINAPI FunctionName(LPVOID), которая исполнялась в потоке.

  •  в dwExitCode помещаем код завершения потока

Чтобы приостановить поток, нужно использовать функцию – SuspendThread. В случае успешной остановки потока функция вернёт предыдущее число остановок данного потока, есть исполнение функции SuspendThread завершится неудачей, то она вернёт -1.

  •  thread – дескриптор потока, который необходимо приостановить. Он должен иметь права доступа: THREAD_SUSPEND_RESUME

Если нужно возобновить данный поток, то необходимо вызвать функцию ResumeThread. При успешном выполнении возвращается предыдущее количество остановок потока, иначе -1.

  •  thread – дескриптор потока, который необходимо возобновить. Он должен иметь права доступа: THREAD_SUSPEND_RESUME

Теперь рассмотрим пример программы, которая осуществляет параллельную многопоточную генерацию и обработку строк двумерной матрицы. То есть каждый отдельный поток будет генерировать строку матрицы и находить произведение нечётных элементов этой строки. В каждый поток будем передавать в качестве параметра указатель на структуру, в которой будет хранится строка матрицы и результат произведения элементов.

Подключим необходимые библиотеки: для вывода результатов на экран, для использования функций WinAPI и для использования времени в качестве инициализирующего элемента генератора случайных чисел.

Определим константу для хранения размера матрицы (в данном примере матрица размером 4×4).

Определим структуру, в которой будем хранить строку матрицы, результат умножения нечётных элементов этой строки и случайное число, которым будет инициализирован генератор случайных чисел в данном потоке (если использовать один и тот же генератор для всех потоков, то, из-за одновременности выполнения, будут генерироваться одинаковые числа для всех строк).

Функция DWORD WINAPI generateAndCalc(void *data), которую будут исполнять потоки (с комментариями):

Функция main() с комментариями:

Работа программы демонстрируется на скриншоте ниже:

parallelComputing

Скачать исходник

 

Параллельные вычисления с помощью WinAPI
5 (100%) 2 votes

Поделиться в соц. сетях:

3 комментария(ев) к статье “Параллельные вычисления с помощью WinAPI

Добавить комментарий для Андрей Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">