Move the sources to trunk
[opencv] / apps / HMMDemo / ThreadHowTo.txt
1 Äàííûé íàáîð ìàêðîñîâ, îïðåäåë¸ííûõ â ôàéëå multiprocdiv.h, ñëóæèò äëÿ óïðîùåíèÿ ïðîöåññà êîíâåðòàöèè àëãîðèòìîâ îñíîâàííûõ íà îäíîì öèêëå, êîòîðûé ïîòðåáëÿåò îñíîâíóþ ÷àñòü âðåìåíè ðàáîòû àëãîðèòìà. Öåëü äàííûõ ìàêðîñîâ - ïåðåëîæèòü âûïîëíåíèå òåëà öèêëà â îòäåëüíûé ïîòîê(è), ÷òî áóäåò îñîáåííî ïîëåçíî íà ìíîãîïðîöåññîðíûõ ñèñòåìàõ. Îñíîâó ìåòîäà ðàçäåëåíèÿ ñîñòàâëÿþò 3 ôóíêöèè. Ïåðâàÿ èç íèõ, óñëîâíî íàçâàííàÿ child, âûïîëíÿåò ñàìî òåëî öèêëà. Âòîðàÿ - control (ñîêðàù¸ííî ctrl) - âñþ ÷àñòü àëãîðèòìà, êîòîðàÿ íàõîäèòñÿ ñíàðóæè öèêëà, à òàêæå çàíèìàåòñÿ ñèíõðîíèçàöèåé è çàíèìàåòñÿ ôîðìèðîâàíèåì äàííûõ äëÿ child-ôóíêöèè. Òðåòüÿ - start-ôóíêöèÿ - çàïóñêàåò è îñòàíàâëèâàåò ctrl-ôóíêöèþ. Child- è ctrl-ôóíêöèè çàïóñêàþòñÿ â îòäåëüíûõ ïîòîêàõ, à start-ôóíêöèÿ ïîñëå çàïóñêà ctrl-ôóíêöèè ñðàçó âûõîäèò, ÷òî äà¸ò âîçìîæíîñòü îêîííîìó ïðèëîæåíèþ ïðîäîëæèòü îáðàáîòêó ñîîáùåíèé.\r
2 \r
3 Èñïîëüçîâàíèå ýòèõ ìàêðîñîâ ëó÷øå ðàññìîòðåòü íà êîíêðåòíîì ïðèìåðå. Ïóñòü íåîáõîäèìî âû÷èñëèòü ñóììó ÷èñåë èç 6 ìàññèâîâ, â êàæäîì èç êîòîðûõ N ÷èñåë. Òîãäà èìååì ñëåäóþùèé òåêñò:\r
4 \r
5 ***********************************************************************\r
6 // MainFrame.cpp\r
7 \r
8 const int N = 30;\r
9 \r
10 int a[6][N];\r
11 \r
12 void CMainFrame::OnDo()\r
13 {\r
14     int i, j;\r
15     int s = 0;\r
16     for( j = 0; j < 6; j ++ )\r
17     {\r
18         for( i = 0; i < N; i ++ )\r
19         {\r
20             s += a[j][i];\r
21         }\r
22     }\r
23 }\r
24 \r
25 ***********************************************************************\r
26 \r
27 Çäåñü åñòü îñíîâíîé öèêë ïî j, êîòîðûé ìû è áóäåì ïåðåâîäèòü íà ìíîãîïîòîêîâóþ îñíîâó.\r
28 Äëÿ íà÷àëà íóæíî îïðåäåëèòü ñòðóêòóðû äëÿ ïåðåäà÷è ïàðàìåòðîâ çàäà÷è â ôóíêöèè ïîòîêîâ. Â íàøåì ñëó÷àå ïîëó÷àåì:\r
29 \r
30 struct ChildInputStruct {\r
31     INPUT_STRUCT_COMMON_PARAMS();\r
32     int* sum;\r
33     int* array;\r
34     int N;\r
35 };\r
36 \r
37 struct ControlInputStruct {\r
38     int* srcArray;\r
39     int* result;\r
40     int N;\r
41 };\r
42 \r
43 Äëÿ ïåðâîé ñòðóêòóðû ïîëå INPUT_STRUCT_COMMON_PARAMS() ÿâëÿåòñÿ îáÿçàòåëüíûì!\r
44 Ïîëå sum ïåðâîé ñòðóêòóðû ïðåäíàçíà÷åíî äëÿ ñóììèðîâàíèÿ â ïàìÿòü ïî ýòîìó óêàçàòåëþ ÷èñåë èç îäíîãî ìàññèâà. Ïîëå array - óêàçàòåëü íà îäèí ìàññèâ. N - ÷èñëî ýëåìåíòîâ â îäíîì ìàññèâå. scrArray - óêàçàòåëü íà âåñü èñõîäíûé ìàññèâ. result - óêàçàòåëü íà ó÷àñòîê ïàìÿòè, êîòîðûé ïðèìåò èòîãîâîå çíà÷åíèå ñóììû. Ñëåäóåò ó÷åñòü, ÷òî result äîëæåí óêàçûâàòü íå íà äèíàìè÷åñêóþ ïåðåìåííóþ, ò.ê. îí áóäåò èñïîëüçîâàòüñÿ â ïîòîêå.\r
45 \r
46 Äàëåå îïðåäåëÿåì ãëîáàëüíûå ïåðåìåííûå, íåîáõîäèìûå äëÿ ôóíêöèîíèðîâàíèÿ ïîòîêîâ. Ýòî äåëàåì ñëåäóþùèì îáðàçîì:\r
47 \r
48 COMMON_GLOBAL_VARS( functionName, ControlInputStruct );\r
49 \r
50 Ïîëå functionName îçíà÷àåò èìÿ ñòàðòîâîé ôóíêöèè ( îíî òàêæå áóäåò íåîäíîêðàòíî ââîäèòüñÿ â ïîñëåäóþùèõ ìàêðîñàõ ). ControlInputStruct - èìÿ ñòðóêòóðû äëÿ ïåðåäà÷è ïàðàìåòðîâ â ctrl-ïîòîê.\r
51 \r
52 Äàëåå ïèøåì child-ôóíêöèþ:\r
53 \r
54 BEGIN_CHILD_THREAD_FUNCTION( functionName, ChildInputStruct );\r
55 \r
56     int i;\r
57 \r
58     BEGIN_CHILD_THREAD_CORE();\r
59 \r
60         *(params->sum) = 0;\r
61 \r
62         for( i = 0; i < params->N; i ++ )\r
63         {\r
64             *(params->sum) += params->array[i];\r
65         }\r
66 \r
67     END_CHILD_THREAD_CORE();\r
68 \r
69 END_CHILD_THREAD_FUNCTION();\r
70 \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
72 \r
73 Ïèøåì óïðàâëÿþùóþ ctrl-ôóíêöèþ:\r
74 \r
75 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct,\r
76                 eraseFunction, beginFunction, endFunction );\r
77 \r
78     int numberOfTasks = 6;\r
79     int sum[6];\r
80 \r
81     BEGIN_CTRL_THREAD_CORE( numberOfTasks );\r
82 \r
83         childParams.sum = sum + i;\r
84         childParams.array = params->srcArray + i * params->N;\r
85         childParams.N = params->N;\r
86 \r
87     END_CTRL_THREAD_CORE();\r
88 \r
89     *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];\r
90 \r
91 END_CTRL_THREAD_FUNCTION();\r
92 \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
98 \r
99 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct, 0, 0, 0 );\r
100 \r
101     int sum[6];\r
102 \r
103     BEGIN_CTRL_THREAD_CORE( 6 );\r
104 \r
105         childParams.sum = sum + i;\r
106         childParams.array = params->srcArray + i * params->N;\r
107         childParams.N = params->N;\r
108 \r
109     END_CTRL_THREAD_CORE();\r
110 \r
111     *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];\r
112 \r
113 END_CTRL_THREAD_FUNCTION();\r
114 \r
115 Äàëåå ïèøåì ñòàðòîâóþ ôóíêöèþ:\r
116 \r
117 BEGIN_START_THREAD_FUNCTION( functionName,( int* srcArray, int* result, int N ),\r
118         ControlInputStruct);\r
119 \r
120     params->srcArray = srcArray;\r
121     params->result = result;\r
122     params->N = N;\r
123 \r
124 END_START_THREAD_FUNCTION();\r
125 \r
126 Çäåñü â ìàêðîñå BEGIN_START_THREAD_FUNCTION() âòîðûì ïàðàìåòðîì çàïèñàíû âõîäíûå äàííûå ñòàðòîâîé ôóíêöèè, à òðåòüèì ïàðàìåòðîâ - èìÿ âõîäíîé ñòðóêòóðû äëÿ ctrl-ôóíêöèè.\r
127 Ìåæäó ìàêðîñàìè BEGIN_START_THREAD_FUNCTION() è END_START_THREAD_FUNCTION() íåîáõîäèìî çàïîëíèòü âõîäíóþ ñòðóêòóðó òèïà ControlInputStruct, çàäàííûé óêàçàòåëåì params.\r
128 \r
129 Äëÿ âîçìîæíîñòè çàïóñêà ñòàðòîâîé ôóíêöèè èç äðóãèõ ôàéëîâ â çàãîëîâî÷íîì ôàéëå íåîáõîäèìî íàïèñàòü:\r
130 \r
131 DEFINE_START_THREAD_FUNCTION( functionName, ( int* srcArray, int* result, int N ) );\r
132 \r
133 \r
134 \r
135 \r
136 Èòàê, ïîëíàÿ ïåðåðàáîòàííàÿ ïðîãðàììà â íàøåì ïðèìåðå áóäåò âûãëÿäåòü ñëåäóþùèì îáðàçîì:\r
137 \r
138 ***********************************************************************\r
139 // MainFrame.cpp\r
140 \r
141 #include "MultiThr.h"\r
142 \r
143 const int N = 30;\r
144 \r
145 int a[6][N];\r
146 int result;\r
147 \r
148 void CMainFrame::OnDo()\r
149 {\r
150     functionName( (int*)a, &result, N );\r
151 }\r
152 ***********************************************************************\r
153 // MultiThr.h\r
154 \r
155 #include "multiprocdiv.h"\r
156 \r
157 DEFINE_START_THREAD_FUNCTION( functionName, ( int* srcArray, int* result, int N ) );\r
158 \r
159 ***********************************************************************\r
160 // MultiThr.cpp\r
161 \r
162 #include "MultiThr.h"\r
163 \r
164 // defining structures\r
165 struct ChildInputStruct {\r
166     INPUT_STRUCT_COMMON_PARAMS();\r
167     int* sum;\r
168     int* array;\r
169     int N;\r
170 };\r
171 \r
172 struct ControlInputStruct {\r
173     int* srcArray;\r
174     int* result;\r
175     int N;\r
176 };\r
177 \r
178 // setting global variables\r
179 COMMON_GLOBAL_VARS( functionName, ControlInputStruct );\r
180 \r
181 // child-function\r
182 BEGIN_CHILD_THREAD_FUNCTION( functionName, ChildInputStruct );\r
183 \r
184     int i;\r
185 \r
186     BEGIN_CHILD_THREAD_CORE();\r
187 \r
188         *(params->sum) = 0;\r
189 \r
190         for( i = 0; i < params->N; i ++ )\r
191         {\r
192             *(params->sum) += params->array[i];\r
193         }\r
194 \r
195     END_CHILD_THREAD_CORE();\r
196 \r
197 END_CHILD_THREAD_FUNCTION();\r
198 \r
199 // control-function\r
200 BEGIN_CTRL_THREAD_FUNCTION( functionName, ControlInputStruct, ChildInputStruct, 0, 0, 0 );\r
201 \r
202     int sum[6];\r
203 \r
204     BEGIN_CTRL_THREAD_CORE( 6 );\r
205 \r
206         childParams.sum = sum + i;\r
207         childParams.array = params->srcArray + i * params->N;\r
208         childParams.N = params->N;\r
209 \r
210     END_CTRL_THREAD_CORE();\r
211 \r
212     *(params->result) = sum[0] + sum[1] + sum[2] + sum[3] + sum[4] + sum[5];\r
213 \r
214 END_CTRL_THREAD_FUNCTION();\r
215 \r
216 // start-function\r
217 BEGIN_START_THREAD_FUNCTION( functionName,( int* srcArray, int* result, int N ),\r
218         ControlInputStruct);\r
219 \r
220     params->srcArray = srcArray;\r
221     params->result = result;\r
222     params->N = N;\r
223 \r
224 END_START_THREAD_FUNCTION();\r
225 \r
226 ***********************************************************************\r
227 \r
228 Ïðèìå÷àíèå 1: ïîâòîðíûé çàïóñê start-ôóíêöèè â ñëó÷àå, åñëè ctrl-ïîòîê åù¸ íå çàâåðø¸í ïðèâåä¸ò ê åãî ïðèíóäèòåëüíîìó çàâåðøåíèþ!\r
229 Ïðèìå÷àíèå 2: äëÿ Windows NT 4.0 â íàñòðîéêàõ ïðîåêòà ñëåäóåò çàäàòü _WIN32_WINNT=4.\r
230 \r
231 \r
232 \r
233 \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