Написание тела для каждого процесса
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Для каждого процесса нунжно создать файл-шаблон. Имя такого файла совпадает с именем процесса и имеет расширение frm (можно воспользоваться файлом Process.frm). В нашем случае имеем три файла: Manager.frm, Worker.frm и Summer.frm. В каждом файле есть процедура, имя которой заканчивается на Body. Внутри нее записывается тело процесса.


10 PROCEDURE ManagerBody;

11 VAR

12 Task : RECORD N:cardinal; a,b:real; END;

13 i,WrkId : cardinal;

14 CONST

15 N : cardinal = 10;

16 BEGIN

17 exportNumIter[0].Send (N, SizeOf(N));

18 Task.N := 10*N;

19 Task.b := 0;

20 FOR i := 1 TO N DO BEGIN

21  Task.a := Task.b;

22  Task.b := i * 1.0 / N;

23  importDemandList.Receive (WrkId, SizeOf(WrkId));

24  exportWorker[WrkId].Send (Task, SizeOf(Task));

25 END;

26 Task.N := 0;

27 FOR i := 1 TO exportWorker.NChannels DO

28  exportWorker[i-1].Send (Task, SizeOf(Task));

29 END;


Файл Manager.frm : тело процесса Manager

Переменная Task описывает задание для рабочего процесса: a,b - границы, N - число интервалов. Константа N, описанная в строке 15, равна числу разбиений отрезка [0;1].

В начале работы посылаем процессу Summer число разбиений N (строка 17) . В строке 23 ждем запроса от одного из рабочих процессов. Запрос представляет собой идентификатор запрашивающего процесса. Получив запрос, отсылаем очередное задание соответствующему рабочему (строка 24).

После того, как задания распределены, нужно сообщить об этом всем рабочим процессам. Для этого служат строки 26-28: по всем каналам порта exportWorker посылаем задание с нулевым числом интервалов - сигнал о завершении работы.


30 PROCEDURE WorkerBody;

31 VAR

32 Task : RECORD N:word; a,b:real; END;

33 S : real;

34 i : word;

35 FUNCTION f(x:real):real;

36 BEGIN

37  Result := 4 / (1 + x*x);

38 END;

39 BEGIN

40 exportDemand[0].Send (FloLib.CopyNumber, SizeOf(cardinal));

41 WHILE (true) DO WITH Task DO BEGIN

42  importArg.Receive (Task, SizeOf(Task));

43  IF (Task.N = 0) THEN EXIT;

44  h := (b-a)/N;

45  S := 0;

46  FOR i := 1 TO N DO

47    S := S + f(a+(i-0.5)*h);

48  S := h*S;

49  exportPartSum[0].Send (S, SizeOf(S));

50  exportDemand[0].Send (FloLib.CopyNumber,SizeOf(cardinal));

51 END;

52 END;


Файл Worker.frm : тело процесса Worker

Бесконечный цикл 41-51 обеспечивает работу процесса до получения сигнала завершения от распределителя работ Manager.

В строке 42 ждем очередное задание Task. Если число интервалов в задании равно 0, то завершаем работу. В противном случае вычисляем частичную сумму на интервале (Task.a; Task.b) и отсылаем ее суммирующему процессу (строки 44-49). В строке 50 обращаемся к распределителю работ за очередным заданием.


53 PROCEDURE SummerBody;

54 VAR

55 N, i : cardinal;

56 F : TextFile;

57 TotalSum, S : real;

58 BEGIN

59 importNumIter.Receive (N, SizeOf(N));

60 TotalSum := 0;

61 FOR i := 1 TO N DO BEGIN

62  importPartSum.Receive (S, SizeOf(S));

63  TotalSum := TotalSum + S;

64 END;

65 AssignFile (F, ‘Pi.result’);

66 Rewrite (F);

67 WriteLn (F, ‘Pi = ’, TotalSum); 

68 CloseFile (F);

69 END;


Файл Summer.frm : тело процесса Summer

В строках 61-64 собираются частичные суммы от всех рабочих процессов и суммируются в переменной TotalSum. Число частичных сумм записываем в переменну N из порта importNumIter (строка 59).







Дата: 2019-07-30, просмотров: 201.