1 Äàííûé íàáîð ìàêðîñîâ, îïðåäåë¸ííûõ â ôàéëå multiprocdiv.h, ñëóæèò äëÿ óïðîùåíèÿ ïðîöåññà êîíâåðòàöèè àëãîðèòìîâ îñíîâàííûõ íà îäíîì öèêëå, êîòîðûé ïîòðåáëÿåò îñíîâíóþ ÷àñòü âðåìåíè ðàáîòû àëãîðèòìà. Öåëü äàííûõ ìàêðîñîâ - ïåðåëîæèòü âûïîëíåíèå òåëà öèêëà â îòäåëüíûé ïîòîê(è), ÷òî áóäåò îñîáåííî ïîëåçíî íà ìíîãîïðîöåññîðíûõ ñèñòåìàõ. Îñíîâó ìåòîäà ðàçäåëåíèÿ ñîñòàâëÿþò 3 ôóíêöèè. Ïåðâàÿ èç íèõ, óñëîâíî íàçâàííàÿ child, âûïîëíÿåò ñàìî òåëî öèêëà. Âòîðàÿ - control (ñîêðàù¸ííî ctrl) - âñþ ÷àñòü àëãîðèòìà, êîòîðàÿ íàõîäèòñÿ ñíàðóæè öèêëà, à òàêæå çàíèìàåòñÿ ñèíõðîíèçàöèåé è çàíèìàåòñÿ ôîðìèðîâàíèåì äàííûõ äëÿ child-ôóíêöèè. Òðåòüÿ - start-ôóíêöèÿ - çàïóñêàåò è îñòàíàâëèâàåò ctrl-ôóíêöèþ. Child- è ctrl-ôóíêöèè çàïóñêàþòñÿ â îòäåëüíûõ ïîòîêàõ, à start-ôóíêöèÿ ïîñëå çàïóñêà ctrl-ôóíêöèè ñðàçó âûõîäèò, ÷òî äà¸ò âîçìîæíîñòü îêîííîìó ïðèëîæåíèþ ïðîäîëæèòü îáðàáîòêó ñîîáùåíèé.
\r
3 Èñïîëüçîâàíèå ýòèõ ìàêðîñîâ ëó÷øå ðàññìîòðåòü íà êîíêðåòíîì ïðèìåðå. Ïóñòü íåîáõîäèìî âû÷èñëèòü ñóììó ÷èñåë èç 6 ìàññèâîâ, â êàæäîì èç êîòîðûõ N ÷èñåë. Òîãäà èìååì ñëåäóþùèé òåêñò:
\r
5 ***********************************************************************
\r
12 void CMainFrame::OnDo()
\r
16 for( j = 0; j < 6; j ++ )
\r
18 for( i = 0; i < N; i ++ )
\r
25 ***********************************************************************
\r
27 Çäåñü åñòü îñíîâíîé öèêë ïî j, êîòîðûé ìû è áóäåì ïåðåâîäèòü íà ìíîãîïîòîêîâóþ îñíîâó.
\r
28 Äëÿ íà÷àëà íóæíî îïðåäåëèòü ñòðóêòóðû äëÿ ïåðåäà÷è ïàðàìåòðîâ çàäà÷è â ôóíêöèè ïîòîêîâ.  íàøåì ñëó÷àå ïîëó÷àåì:
\r
30 struct ChildInputStruct {
\r
31 INPUT_STRUCT_COMMON_PARAMS();
\r
37 struct ControlInputStruct {
\r
43 Äëÿ ïåðâîé ñòðóêòóðû ïîëå INPUT_STRUCT_COMMON_PARAMS() ÿâëÿåòñÿ îáÿçàòåëüíûì!
\r
44 Ïîëå sum ïåðâîé ñòðóêòóðû ïðåäíàçíà÷åíî äëÿ ñóììèðîâàíèÿ â ïàìÿòü ïî ýòîìó óêàçàòåëþ ÷èñåë èç îäíîãî ìàññèâà. Ïîëå array - óêàçàòåëü íà îäèí ìàññèâ. N - ÷èñëî ýëåìåíòîâ â îäíîì ìàññèâå. scrArray - óêàçàòåëü íà âåñü èñõîäíûé ìàññèâ. result - óêàçàòåëü íà ó÷àñòîê ïàìÿòè, êîòîðûé ïðèìåò èòîãîâîå çíà÷åíèå ñóììû. Ñëåäóåò ó÷åñòü, ÷òî result äîëæåí óêàçûâàòü íå íà äèíàìè÷åñêóþ ïåðåìåííóþ, ò.ê. îí áóäåò èñïîëüçîâàòüñÿ â ïîòîêå.
\r
46 Äàëåå îïðåäåëÿåì ãëîáàëüíûå ïåðåìåííûå, íåîáõîäèìûå äëÿ ôóíêöèîíèðîâàíèÿ ïîòîêîâ. Ýòî äåëàåì ñëåäóþùèì îáðàçîì:
\r
48 COMMON_GLOBAL_VARS( functionName, ControlInputStruct );
\r
50 Ïîëå functionName îçíà÷àåò èìÿ ñòàðòîâîé ôóíêöèè ( îíî òàêæå áóäåò íåîäíîêðàòíî ââîäèòüñÿ â ïîñëåäóþùèõ ìàêðîñàõ ). ControlInputStruct - èìÿ ñòðóêòóðû äëÿ ïåðåäà÷è ïàðàìåòðîâ â ctrl-ïîòîê.
\r
52 Äàëåå ïèøåì child-ôóíêöèþ:
\r
54 BEGIN_CHILD_THREAD_FUNCTION( functionName, ChildInputStruct );
\r
58 BEGIN_CHILD_THREAD_CORE();
\r
62 for( i = 0; i < params->N; i ++ )
\r
64 *(params->sum) += params->array[i];
\r
67 END_CHILD_THREAD_CORE();
\r
69 END_CHILD_THREAD_FUNCTION();
\r
71 Ïîëå functionName çäåñü è äàëåå èìååò òîò æå ñìûñë, ÷òî è â COMMON_GLOBAL_VARS. params ÿâëÿåòñÿ óêàçàòåëåì íà ñòðóêòóðó ChildInputStruct, ïîäàííóþ ïîòîêó â êà÷åñòâå ïàðàìåòðà. Îïðåäåëåíèå äîïîëíèòåëüíûõ ïåðåìåííûõ ïðîèçâîäèòñÿ ìåæäó ìàêðîñàìè BEGIN_CHILD_THREAD_FUNCTION() è BEGIN_CHILD_THREAD_CORE(). Âñå ïîëåçíûå äåéñòâèÿ ïðîèçîäÿòñÿ ìåæäó ìàêðîñàìè BEGIN_CHILD_THREAD_CORE() è END_CHILD_THREAD_CORE().  íàøåì ñëó÷àå òàì ñíà÷àëà îáíóëÿåòñÿ çíà÷åíèå ñóììû, à çàòåì â öèêëå ê íåé ïðèáàâëÿþòñÿ çíà÷åíèÿ èç ìàññèâà. Ìàêðîñ END_CHILD_THREAD_FUNCTION() äåëàåò âñ¸ äëÿ âûõîäà èç ôóíêöèè.
\r
73 Ïèøåì óïðàâëÿþùóþ ctrl-ôóíêöèþ:
\r
75 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct,
\r
76 eraseFunction, beginFunction, endFunction );
\r
78 int numberOfTasks = 6;
\r
81 BEGIN_CTRL_THREAD_CORE( numberOfTasks );
\r
83 childParams.sum = sum + i;
\r
84 childParams.array = params->srcArray + i * params->N;
\r
85 childParams.N = params->N;
\r
87 END_CTRL_THREAD_CORE();
\r
89 *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];
\r
91 END_CTRL_THREAD_FUNCTION();
\r
93 Çäåñü ControlInputStruct è ChildInputStruct - èìåíà âõîäíûõ ñòðóêòóð äàííûõ äëÿ ctrl- è child-ôèíêöèé ñîîòâåòñòâåííî. eraseFunction, beginFunction è endFunction - óêàçàòåëè íà ôóíêöèè, òèïà bool function( void* ). Âñåì ôóíêöèÿì íà âõîä ïîäà¸òñÿ óêàçàòåëü íà ñòðóêòóðó ControlInputStruct, ñîäåðæàùóþ íà÷àëüíûå äàííûå äëÿ óïðàâëÿþùåãî ïîòîêà. Åñëè êàêîé-òî èç ýòèõ 3-õ óêàçàòåëåé ðàâåí íóëþ, òî ñîîòâåòñòâóþùàÿ ôóíêöèÿ íå âûçûâàåòñÿ. eraseFunction - ôóíêöèÿ, âûçûâàåìàÿ â ñëó÷àå äîñðî÷íîãî çàâåðøåíèÿ ïîòîêà â ñëó÷àå åãî ïðèíóäèòåëüíîãî çàâåðøåíèÿ, beginFunction - ôóíêöèÿ, âûçûâàåìàÿ äî íà÷àëà âû÷èñëåíèé ( ìîæåò èñïîëüçîâàòüñÿ äëÿ ñìåíû ñòàòóñà ýëåìåíòîâ óïðàâëåíèÿ îêíà, íî â ýòîì ñëó÷àå óêàçàòåëü íà êëàññ îêíà åñòåññòâåííî äîëæåí âõîäèòü â ñòðóêòóðó ControlInputStruct ). endFunction - ôóíêöèÿ, âûçûâàåìàÿ ïîñëå îêîí÷àíèÿ ñ÷¸òà ( ñëó÷àé, ïðîòèâîïîëîæíûé ôóíêöèè beginFunction ).  íàøåì ñëó÷àå ýòè ôóíêöèè ìîæíî íå ïèñàòü è ïîñòàâèòü â êà÷åñòâå ïàðàìåòðîâ íóëè.
\r
94 numberOfTasks - îáùåå ÷èñëî çàäà÷ ( â ìàêðîñå BEGIN_CTRL_THREAD_CORE() ìîæåò ñòîÿòü ïðîñòî ÷èñëî 6 â íàøåì ñëó÷àå ).
\r
95 Ìåæäó ìàêðîñàìè BEGIN_CTRL_THREAD_FUNCTION() è BEGIN_CTRL_THREAD_CORE() ñëåäóåò ïîìåùàòü îïðåäåëåíèå ëîêàëüíûõ ïåðåìåííûõ è âû÷èñëåíèå, åñëè òàêîå íåîáõîäèìî, îáùåãî êîëè÷åñòâà øàãîâ â ðàçâîðà÷èâàåìîì öèêëå, à òàêæå âñå ïðåäâàðèòåëüíûå âû÷èñëåíèÿ. Ìåæäó ìàêðîñàìè BEGIN_CTRL_THREAD_CORE() è END_CTRL_THREAD_CORE() ñëåäóåò çàïîëíèòü ñòðóêòóðó childParams - ñòðóêòóðó òèïà ChildInputStruct íîâûì çàäàíèåì.  íàøåì ñëó÷àå çàïîëíÿþòñÿ ïîëÿ sum, array è N ñîîòâåòñòâóþùèìè çíà÷åíèÿìè. Âíóòðè ýòèõ ìàêðîñîâ ïåðåìåííàÿ i îòâå÷àåò çà òåêóùèé íîìåð çàäàíèÿ.
\r
96 Ìåæäó ìàêðîñàìè END_CTRL_THREAD_CORE() è END_CTRL_THREAD_FUNCTION() ïîìåùàåòñÿ êîä, êîòîðûé äîëæåí âûïîëíÿòüñÿ ïîñëå çàâåðøåíèÿ âñåõ child-ïðîöåññîâ, íî ïåðåä âûõîäîì èç ctrl-ïðîöåññà.  íàøåì ïðèìåðå â ýòîì ìåñòå ñòîèò âû÷èñëåíèå ñóììû ýëåìåíòîâ èç ìàññèâà sum è çàíåñåíèå ðåçóëüòàòà ïî àäðåñó result.
\r
97 Òàêèì îáðàçîì, ctrl-ôóíêöèþ â íàøåì ñëó÷àå íóæíî çàïèñàòü ñëåäóþùèì îáðàçîì:
\r
99 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct, 0, 0, 0 );
\r
103 BEGIN_CTRL_THREAD_CORE( 6 );
\r
105 childParams.sum = sum + i;
\r
106 childParams.array = params->srcArray + i * params->N;
\r
107 childParams.N = params->N;
\r
109 END_CTRL_THREAD_CORE();
\r
111 *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];
\r
113 END_CTRL_THREAD_FUNCTION();
\r
115 Äàëåå ïèøåì ñòàðòîâóþ ôóíêöèþ:
\r
117 BEGIN_START_THREAD_FUNCTION( functionName,( int* srcArray, int* result, int N ),
\r
118 ControlInputStruct);
\r
120 params->srcArray = srcArray;
\r
121 params->result = result;
\r
124 END_START_THREAD_FUNCTION();
\r
126 Çäåñü â ìàêðîñå BEGIN_START_THREAD_FUNCTION() âòîðûì ïàðàìåòðîì çàïèñàíû âõîäíûå äàííûå ñòàðòîâîé ôóíêöèè, à òðåòüèì ïàðàìåòðîâ - èìÿ âõîäíîé ñòðóêòóðû äëÿ ctrl-ôóíêöèè.
\r
127 Ìåæäó ìàêðîñàìè BEGIN_START_THREAD_FUNCTION() è END_START_THREAD_FUNCTION() íåîáõîäèìî çàïîëíèòü âõîäíóþ ñòðóêòóðó òèïà ControlInputStruct, çàäàííûé óêàçàòåëåì params.
\r
129 Äëÿ âîçìîæíîñòè çàïóñêà ñòàðòîâîé ôóíêöèè èç äðóãèõ ôàéëîâ â çàãîëîâî÷íîì ôàéëå íåîáõîäèìî íàïèñàòü:
\r
131 DEFINE_START_THREAD_FUNCTION( functionName, ( int* srcArray, int* result, int N ) );
\r
136 Èòàê, ïîëíàÿ ïåðåðàáîòàííàÿ ïðîãðàììà â íàøåì ïðèìåðå áóäåò âûãëÿäåòü ñëåäóþùèì îáðàçîì:
\r
138 ***********************************************************************
\r
141 #include "MultiThr.h"
\r
148 void CMainFrame::OnDo()
\r
150 functionName( (int*)a, &result, N );
\r
152 ***********************************************************************
\r
155 #include "multiprocdiv.h"
\r
157 DEFINE_START_THREAD_FUNCTION( functionName, ( int* srcArray, int* result, int N ) );
\r
159 ***********************************************************************
\r
162 #include "MultiThr.h"
\r
164 // defining structures
\r
165 struct ChildInputStruct {
\r
166 INPUT_STRUCT_COMMON_PARAMS();
\r
172 struct ControlInputStruct {
\r
178 // setting global variables
\r
179 COMMON_GLOBAL_VARS( functionName, ControlInputStruct );
\r
182 BEGIN_CHILD_THREAD_FUNCTION( functionName, ChildInputStruct );
\r
186 BEGIN_CHILD_THREAD_CORE();
\r
188 *(params->sum) = 0;
\r
190 for( i = 0; i < params->N; i ++ )
\r
192 *(params->sum) += params->array[i];
\r
195 END_CHILD_THREAD_CORE();
\r
197 END_CHILD_THREAD_FUNCTION();
\r
199 // control-function
\r
200 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct, 0, 0, 0 );
\r
204 BEGIN_CTRL_THREAD_CORE( 6 );
\r
206 childParams.sum = sum + i;
\r
207 childParams.array = params->srcArray + i * params->N;
\r
208 childParams.N = params->N;
\r
210 END_CTRL_THREAD_CORE();
\r
212 *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];
\r
214 END_CTRL_THREAD_FUNCTION();
\r
217 BEGIN_START_THREAD_FUNCTION( functionName,( int* srcArray, int* result, int N ),
\r
218 ControlInputStruct);
\r
220 params->srcArray = srcArray;
\r
221 params->result = result;
\r
224 END_START_THREAD_FUNCTION();
\r
226 ***********************************************************************
\r
228 Ïðèìå÷àíèå 1: ïîâòîðíûé çàïóñê start-ôóíêöèè â ñëó÷àå, åñëè ctrl-ïîòîê åù¸ íå çàâåðø¸í ïðèâåä¸ò ê åãî ïðèíóäèòåëüíîìó çàâåðøåíèþ!
\r
229 Ïðèìå÷àíèå 2: äëÿ Windows NT 4.0 â íàñòðîéêàõ ïðîåêòà ñëåäóåò çàäàòü _WIN32_WINNT=4.
\r
234 Òàêæå åñòü íåêîòîðûå âñïîìîãàòåëüíûå ñðåäñòâà äëÿ áîëåå äåòàëüíîãî óïðàâëåíèÿ:
\r
235 1) Äëÿ îïðåäåëåíèÿ ñîñòîÿíèÿ ctrl ïîòîêà ñëóæèò ìàêðîñ IS_THREAD_STILL_WORKING( functionName ), êîòîðûé âîçâðàùàåò true, åñëè ctrl-ïîòîê âñ¸ åù¸ ðàáîòàåò è false - â ïðîòèâíîì ñëó÷àå. Åñëè start-ôóíêöèÿ åù¸ íè ðàçó íå çàïóñêàëàñü, òî ìàêðîñ âåðí¸ò íåêîððåêòíîå çíà÷åíèå.
\r
236 2) Äëÿ èñïîëüçîâàíèÿ êðèòè÷åñêèõ ñåêöèé âíóòðè child- è ctrl-ôóíêöèé ìîæíî èñïîëüçîâàòü ìàêðîñû ENTER_THREAD_CRITICAL_SECTION() è LEAVE_THREAD_CRITICAL_SECTION(), òîëüêî îáðàçóþùèå ôóíêöèè ìàêðîñû íå ìîãóò ñòîÿòü ìåæäó ENTER_THREAD_CRITICAL_SECTION() è LEAVE_THREAD_CRITICAL_SECTION().
\r
237 3) Äëÿ òðàññèðîâêè ïîòîêîâ âìåñòî ìàêðîñîâ âèäà _RPT0, _RPT1 è ò.ä. ìîæíî èñïîëüçîâàòü ìàêðîñû thrWriteToTrace0, thrWriteToTrace1 è ò.ä., êîòîðûå àâòîìàòè÷åñêè íå áóäóò ñêîìïèëèðîâàíû äëÿ Release-âåðñèè.
\r