Пример создания параллельного процесса Пример последовательной обработки на языке С

Следующий пример демонстрирует параллельную обработку в операционной системе UNIX. Как и при описании большинства понятий программирования, в этой книге используется простейший синтаксис; программа занимает всего несколько строк кода. Например, ниже приведена обычная программа на языке С, которая выводит целые числа от 1 до 5 вместе с их суммой. Вы можете получить все: Отдел продаж курс обучения. Доска объявлений - AutoRepo. Компьютерная помощь все по 400руб компьютерный ремонт. Сделай компьютер удобным.

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

sum =0; for (i я 1 j i <= 5 ; i++) { /* Наращивать в цикле значение */ /* переменной i от 1 до 5 */ printf(" The value of i is %d\n", i); fflush(stdout); /* Вывести содержимое буфера на*/ /* устройство вывода */ sum += i; } printf(" The sum is %d\n", sum); exit(0); /* Завершить программу */ }  

После вызова на выполнение программа выводит на экран шесть строк:

The value of i is 1 The value of i is 2 The value of i is 3 The value of i is 4 The value of i is 5 The sum is 15  3.5.2. Параллельная версия

Для создания нового процесса в программе вызывается системная функция fork3. По существу, fork делит работающую программу на два (почти) одинаковых процесса и запускает поток на выполнение в новом процессе с того же места в коде. Потоки в двух процессах продолжают работу так, как если бы два пользователя одновременно запустили две копии этого приложения. Например, в следующей модифицированной версии приведенного выше примера запускается функция fork для создания нового процесса. (Следует отметить, что введение средств параллельной работы полностью меняет смысл программы, несмотря на то, что вызов функции fork занимает только одну строку кода.)

После вызова на выполнение этой параллельной версии программы система создает процесс с единственным потоком, выполняющим данный код. Однако после достижения потоком выполнения вызова функции fork система формирует дубликат процесса, создает один поток в новом процессе и разрешает продолжить выполнение и первоначальному, и вновь созданному потоку. Безусловно, каждый поток имеет собственную копию локальных переменных, используемых в программе. По существу, лучше всего можно представить себе, что происходит, если предположить, что система создает вторую копию всей работающей программы. Затем представьте себе, что начинают работать обе копии (точно так же, как если бы два пользователя вызвали на выполнение эту программу одновременно).

Чтобы понять, как работает функция fork, представьте себе, что эта функция "вынуждает" операционную систему сделать копию выполняемой программы и разрешить обеим копиям работать одновременно.

В одной конкретной однопроцессорной системе выполнение параллельной программы, представленной в этом примере, привело к получению двенадцати строк вывода.

На используемом компьютере поток в первом процессе выполнялся настолько быстро, что смог закончить работу еще до того, как начал действовать поток во втором процессе. Сразу после окончания работы последнего потока операционная система завершает весь процесс. После закрытия первого процесса операционная система переключает процессор на поток второго процесса, который также работает до завершения. Все выполнение программы заняло меньше секунды. Издержки операционной системы, связанные с переключением между потоками, завершением процессов и обработкой системных вызовов, включая вызов функции fork и вызовы, необходимые для вывода данных на устройство вывода, составили менее 20% общих затрат времени.

3.5.3. Квантование времени

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

Механизм квантования времени пытается распределять все доступные ресурсы процессора равным образом между всеми имеющимися потоками. Если вызваны на выполнение только два потока и компьютер имеет один процессор, то каждый из потоков получает приблизительно 50% процессорного времени. Если же на компьютере с одним процессором вызвано на выполнение N потоков, то каждый получает приблизительно 1/N процессорного времени. Поэтому создается впечатление, что все потоки функционируют с одинаковой скоростью, независимо от их количества. Если в системе выполняется много потоков, скорость работы каждого из них становится низкой; если потоков мало, скорость повышается.

Для ознакомления с эффектом квантования времени требуется пример программы, в которой каждый поток выполняется дольше по сравнению с выделенным квантом времени. Дополним приведенную выше параллельную программу таким образом, чтобы в ней происходило 10000 итераций цикла вместо 5:

include include int sum; main() { int i? sum = 0? fork(); for (i = 1 ? i <= 10000 ; i++) { printf(" The value of i is %d\n", i); fflush(stdout); sum += i? } printf(" The total is %d\n", sum); exit(O); }  

Если полученная параллельная программа будет вызвана на выполнение в той же системе, что и прежде, она выдаст 20002 строки вывода. Однако теперь в начале распечатки не будет находиться весь вывод потока первого процесса, за которым следует весь вывод потока второго процесса; вывод этих потоков будет чередоваться. В течение одного кванта времени первый поток выполнит 74 итерации еще до того, как начнет выполняться второй поток. Затем второй поток выполнит 63 итерации до того, как система снова переключится на первый поток. В течение следующих квантов времени каждый из потоков будет получать количество процессорного времени, достаточное для выполнения от 60 до 90 итераций. Безусловно, эти два потока будут конкурировать со всеми другими потоками, работающими на компьютере, поэтому фактическая скорость выполнения будет немного колебаться в зависимости от состава смеси активных программ.

Некоторые механизмы квантования времени предусматривают равномерное распределение процессорного времени между процессами, а затем дальнейшее распределение времени процесса между его потоками.

Похожие статьи Меню Опрос Фото Популярное