在进行编程时,难免会进行多线程的操作,win32 api使用起来诸多不便,因此我用C++封装了一下。
包含:
线程基类Thread
线程组管理ThreadManager
临界区锁CriticalSection
当然实际运用中不可能只有这点,大家根据需要自己加代码完成吧。比如事件锁,互斥锁,信号锁等等
包含:
线程基类Thread
线程组管理ThreadManager
临界区锁CriticalSection
当然实际运用中不可能只有这点,大家根据需要自己加代码完成吧。比如事件锁,互斥锁,信号锁等等
001 | #include <windows.h> |
002 | #include <iostream> |
003 | #include <string> |
004 | #include <vector> |
005 | #include <process.h> |
006 | #include <assert.h> |
007 | |
008 | // Thread.h --------------------------------------
|
009 | |
010 | /* 线程封装 */ |
011 | class
Thread |
012 | { |
013 | public :
|
014 | typedef
unsigned long
handle_t; |
015 | typedef
unsigned ( __stdcall * start_routine )( void
* param ); |
016 | bool
want_stop; |
017 | bool
auto_delete; |
018 | unsigned thread_id;
|
019 | unsigned exit_code;
|
020 | |
021 | Thread(
void );
|
022 | virtual
~Thread( void
); |
023 | virtual
void run() = 0;
|
024 | |
025 | void
start( void
); |
026 | void
pause( void
); |
027 | void
close( void
); |
028 | void
wait( unsigned long
ms = INFINITE ); |
029 | void
forceStop( void
); |
030 | |
031 | handle_t handle(
void ) {
return _thread; }
|
032 | private :
|
033 | handle_t _thread;
|
034 | static
unsigned __stdcall _start_run( Thread * thread_ptr );
|
035 | |
036 | Thread( Thread
const & );
|
037 | Thread & operator = ( Thread
const & );
|
038 | }; |
039 | |
040 | // Thread.cpp ------------------------------------
|
041 | Thread::Thread( void
) : _thread(0), thread_id(0), want_stop( false ), auto_delete( true ), exit_code(0)
|
042 | { |
043 | _thread = _beginthreadex( NULL, 0, (start_routine)_start_run,
this , CREATE_SUSPENDED, & this ->thread_id );
|
044 | } |
045 | |
046 | Thread::~Thread( void
) |
047 | { |
048 | this ->close();
|
049 | } |
050 | |
051 | void
Thread::start( void
) |
052 | { |
053 | ResumeThread( ( HANDLE )_thread );
|
054 | } |
055 | |
056 | void
Thread::pause( void
) |
057 | { |
058 | SuspendThread( ( HANDLE )_thread );
|
059 | } |
060 | |
061 | void
Thread::close( void
) |
062 | { |
063 | if
( _thread ) |
064 | {
|
065 | CloseHandle( ( HANDLE )_thread );
|
066 | _thread = 0;
|
067 | }
|
068 | } |
069 | |
070 | void
Thread::wait( unsigned long
ms /*= INFINITE */
) |
071 | { |
072 | WaitForSingleObject( ( HANDLE )_thread, ms );
|
073 | } |
074 | |
075 | unsigned __stdcall Thread::_start_run( Thread * thread_ptr )
|
076 | { |
077 | thread_ptr->run();
|
078 | unsigned exit_code = thread_ptr->exit_code;
|
079 | |
080 | if
( thread_ptr->auto_delete ) |
081 | delete
thread_ptr; |
082 | |
083 | return
exit_code; |
084 | } |
085 | |
086 | void
Thread::forceStop( void
) |
087 | { |
088 | TerminateThread( ( HANDLE )_thread, exit_code );
|
089 | } |
090 | |
091 | // ThreadManager.h ----------------------------------------
|
092 | /* 线程管理器 */ |
093 | template
< typename _Thread>
class ThreadManager
|
094 | { |
095 | public :
|
096 | typedef
typename std::vector<_Thread *> thread_array;
|
097 | |
098 | ThreadManager(
void ) {}
|
099 | ~ThreadManager(
void )
|
100 | {
|
101 | thread_array::iterator it;
|
102 | for
( it = _thread_arr.begin(); it != _thread_arr.end(); it++ )
|
103 | {
|
104 | delete
*it; |
105 | }
|
106 | _thread_arr.clear();
|
107 | }
|
108 | template
< typename
_ARG_T1> void
create( int count, _ARG_T1 arg1 )
|
109 | {
|
110 | int
i; |
111 | for
( i = 0; i < count; i++ ) |
112 | {
|
113 | _Thread * th_ptr =
new _Thread(arg1);
|
114 | th_ptr->auto_delete =
false ;
|
115 | _thread_arr.push_back(th_ptr);
|
116 | }
|
117 | }
|
118 | template
< typename
_ARG_T1, typename
_ARG_T2 > void
create( int count, _ARG_T1 arg1, _ARG_T2 arg2 )
|
119 | {
|
120 | int
i; |
121 | for
( i = 0; i < count; i++ ) |
122 | {
|
123 | _Thread * th_ptr =
new _Thread( arg1, arg2 );
|
124 | th_ptr->auto_delete =
false ;
|
125 | _thread_arr.push_back(th_ptr);
|
126 | }
|
127 | }
|
128 | template
< typename
_ARG_T1, typename
_ARG_T2, typename
_ARG_T3> void
create( int count, _ARG_T1 arg1, _ARG_T2 arg2, _ARG_T3 arg3 )
|
129 | {
|
130 | int
i; |
131 | for
( i = 0; i < count; i++ ) |
132 | {
|
133 | _Thread * th_ptr =
new _Thread( arg1, arg2, arg3 );
|
134 | th_ptr->auto_delete =
false ;
|
135 | _thread_arr.push_back(th_ptr);
|
136 | }
|
137 | }
|
138 | void
create( int
count ) |
139 | {
|
140 | int
i; |
141 | for
( i = 0; i < count; i++ ) |
142 | {
|
143 | _Thread * th_ptr =
new _Thread();
|
144 | th_ptr->auto_delete =
false ;
|
145 | _thread_arr.push_back(th_ptr);
|
146 | }
|
147 | }
|
148 | void
start( void
) |
149 | {
|
150 | thread_array::iterator it;
|
151 | for
( it = _thread_arr.begin(); it != _thread_arr.end(); it++ )
|
152 | {
|
153 | (*it)->start();
|
154 | }
|
155 | }
|
156 | void
pause( void
) |
157 | {
|
158 | thread_array::iterator it;
|
159 | for
( it = _thread_arr.begin(); it != _thread_arr.end(); it++ )
|
160 | {
|
161 | (*it)->pause();
|
162 | }
|
163 | }
|
164 | void
close( void
) |
165 | {
|
166 | thread_array::iterator it;
|
167 | for
( it = _thread_arr.begin(); it != _thread_arr.end(); it++ )
|
168 | {
|
169 | (*it)->close();
|
170 | }
|
171 | }
|
172 | void
wait( unsigned long
ms = INFINITE ) |
173 | {
|
174 | int
count = _thread_arr.size(); |
175 | assert ( count <= MAXIMUM_WAIT_OBJECTS );
|
176 | HANDLE
* th_hs = new
HANDLE [count];
|
177 | int
i; |
178 | for
( i = 0; i < count; ++i ) |
179 | {
|
180 | th_hs[i] = ( HANDLE )_thread_arr[i]->handle();
|
181 | }
|
182 | WaitForMultipleObjects( count, th_hs, TRUE, ms );
|
183 | delete
[] th_hs; |
184 | }
|
185 | private :
|
186 | thread_array _thread_arr;
|
187 | |
188 | ThreadManager( ThreadManager
const & );
|
189 | ThreadManager & operator = ( ThreadManager
const & );
|
190 | }; |
191 | |
192 | // Lock.h -----------------------------------------------------
|
193 | /* 临界区锁 */ |
194 | class
CriticalSection |
195 | { |
196 | public :
|
197 | CriticalSection(
void );
|
198 | ~CriticalSection(
void );
|
199 | void
lock( void
); |
200 | void
unlock( void
); |
201 | bool
trylock( void
); |
202 | private :
|
203 | CRITICAL_SECTION _cs;
|
204 | |
205 | CriticalSection( CriticalSection
const & );
|
206 | CriticalSection & operator = ( CriticalSection
const & );
|
207 | }; |
208 | |
209 | // Lock.cpp -----------------------------------------------------
|
210 | CriticalSection::CriticalSection(
void ) |
211 | { |
212 | ZeroMemory( &_cs,
sizeof (_cs) );
|
213 | InitializeCriticalSection(&_cs);
|
214 | } |
215 | |
216 | CriticalSection::~CriticalSection(
void ) |
217 | { |
218 | DeleteCriticalSection(&_cs);
|
219 | } |
220 | |
221 | void
CriticalSection::lock( void
) |
222 | { |
223 | EnterCriticalSection(&_cs);
|
224 | } |
225 | |
226 | void
CriticalSection::unlock( void
) |
227 | { |
228 | LeaveCriticalSection(&_cs);
|
229 | } |
230 | |
231 | bool
CriticalSection::trylock( void
) |
232 | { |
233 | return
TryEnterCriticalSection(&_cs); |
234 | } |
235 | |
236 | // Test.cpp --------------------------------------------------------
|
237 | /*自定义一个线程*/ |
238 | class
MyThread : public
Thread |
239 | { |
240 | public :
|
241 | MyThread( CriticalSection * cs_lock ) : _cs_lock(cs_lock)
|
242 | {
|
243 | }
|
244 | MyThread( CriticalSection * cs_lock, std::string name ) : _cs_lock(cs_lock), _name(name)
|
245 | {
|
246 | }
|
247 | virtual
void run() |
248 | {
|
249 | int
i = 0; |
250 | while
( ! this ->want_stop && i++ < 100 )
|
251 | {
|
252 | _cs_lock->lock();
|
253 | std::cout << _name <<
" " << this ->thread_id <<
" 正在运行...\n" ;
|
254 | _cs_lock->unlock();
|
255 | }
|
256 | }
|
257 | private :
|
258 | CriticalSection * _cs_lock;
|
259 | std::string _name;
|
260 | }; |
261 | |
262 | |
263 | int
main() |
264 | { |
265 | std::string cmd;
|
266 | CriticalSection cs;
|
267 | class
MyThreadOnce : public
Thread |
268 | {
|
269 | public :
|
270 | MyThreadOnce( CriticalSection * cs ) : _cs(cs) {}
|
271 | ~MyThreadOnce(
void )
|
272 | {
|
273 | _cs->lock();
|
274 | std::cout <<
this ->thread_id <<
" 析构!\n" ; |
275 | _cs->unlock();
|
276 | }
|
277 | virtual
void run() |
278 | {
|
279 | _cs->lock();
|
280 | std::cout <<
this ->thread_id <<
" 运行完毕!\n" ;
|
281 | _cs->unlock();
|
282 | }
|
283 | private :
|
284 | CriticalSection * _cs;
|
285 | };
|
286 | |
287 | // 启动一个线程,运行完毕自动析构
|
288 | ( new
MyThreadOnce(&cs))->start(); |
289 | |
290 | // 管理一组线程,调用create()函数创建线程,可最多传3个参数调用构造函数
|
291 | ThreadManager<MyThread> mgr;
|
292 | mgr.create( 5, &cs );
|
293 | mgr.create( 5, &cs, std::string( "Output" ) );
|
294 | mgr.start();
|
295 | |
296 | // 接受用户输入
|
297 | while
( std::cin >> cmd ) |
298 | {
|
299 | if
( cmd == "stop"
) |
300 | {
|
301 | break ;
|
302 | }
|
303 | }
|
304 | |
305 | return
0; |
306 | } |