在进行编程时,难免会进行多线程的操作,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 | } |