thread.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
33 #ifndef __INCLUDE_MIST_THREAD__
34 #define __INCLUDE_MIST_THREAD__
35 
36 
37 #ifndef __INCLUDE_MIST_CONF_H__
38 #include "config/mist_conf.h"
39 #endif
40 
41 #ifndef __INCLUDE_MIST_SINGLETON__
42 #include "singleton.h"
43 #endif
44 
45 
46 // スレッド用ライブラリのインクルード
47 // UNIX系とWindows用を使い分ける
48 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
49  // スレッドサポートはしないので特に必要なインクルードファイルは無し
50  #define __THREAD_POOL_SUPPORT__ 0
51 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
52  #if !defined( _WIN32_WINNT )
53  #define __THREAD_POOL_SUPPORT__ 0
54  #pragma message( "To use mist thread pool functionality, you must define _WIN32_WINNT (>=0x0400) in the project setting page." )
55  #elif _WIN32_WINNT < 0x0400
56  #define __THREAD_POOL_SUPPORT__ 0
57  #pragma message( "To use mist thread pool functionality, _WIN32_WINNT must be greater than 0x0400." )
58  #else
59  #define __THREAD_POOL_SUPPORT__ 1
60  #endif
61 
62  #include <windows.h>
63  #include <process.h>
64  #include <mmsystem.h>
65  #pragma comment ( lib, "winmm.lib" )
66 #else
67  #include <pthread.h>
68  #include <unistd.h>
69  #include <time.h>
70  #include <errno.h>
71  #include <sys/time.h>
72  #define __THREAD_POOL_SUPPORT__ 1
73 #endif
74 
75 #ifndef INFINITE
76 #define INFINITE ( ( unsigned long ) -1 )
77 #endif
78 
79 #include <map>
80 #include <vector>
81 #include <list>
82 #include <string>
83 
84 
85 // mist名前空間の始まり
87 
88 
89 
90 // スレッド用関数
91 typedef unsigned long ThreadExitCode;
92 typedef ThreadExitCode ( LPTHREADFUNC ) ( void *thread_param );
93 
94 
95 // スレッドを操作する,識別する変数
96 struct thread_dmy_class{ };
97 
98 // スレッドを操作する一番ベースとなるクラス
99 struct thread_object
100 {
101  virtual bool create( ) = 0;
102  virtual bool wait( unsigned long dwMilliseconds = INFINITE ) = 0;
103  virtual bool close( ) = 0;
104  virtual ~thread_object( ){ }
105 };
106 
107 
115 
116 
124 inline size_t get_cpu_num( )
125 {
126 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
127  // スレッドサポートはしないのでCPU数は常に1
128  return( 1 );
129 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
130  SYSTEM_INFO sysInfo;
131  GetSystemInfo( &sysInfo );
132  return( static_cast< size_t >( sysInfo.dwNumberOfProcessors ) );
133 #else
134  return( static_cast< size_t >( sysconf( _SC_NPROCESSORS_ONLN ) ) );
135 #endif
136 }
137 
138 
140 inline void sleep( size_t dwMilliseconds )
141 {
142 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
143  SleepEx( static_cast< DWORD >( dwMilliseconds ), false );
144 #else
145  timespec treq, trem;
146  treq.tv_sec = static_cast< time_t >( dwMilliseconds / 1000 );
147  treq.tv_nsec = static_cast< long >( ( dwMilliseconds % 1000 ) * 1000000 );
148 
149  while( nanosleep( &treq, &trem ) != 0 )
150  {
151  treq = trem;
152  }
153 #endif
154 }
155 
156 
190 {
191 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
192  typedef char lock_object_type; // スレッドサポートはしないのでダミー変数用意
193 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
194  typedef CRITICAL_SECTION lock_object_type; // Windows用のロックオブジェクト(CRITIFCALSECTIONを利用)
195 #else
196  typedef pthread_mutex_t lock_object_type; // pthreadライブラリでのロックオブジェクト
197 #endif
198 
199  lock_object_type __lock__;
200 
201 public:
204  {
205 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
206  // スレッドサポートはしないので特に必何もしない
207 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
208  //InitializeCriticalSectionAndSpinCount( &__lock__, 4000 ); // クリティカルセクションオブジェクトを初期化
209  InitializeCriticalSection( &__lock__ ); // クリティカルセクションオブジェクトを初期化
210 #else
211  pthread_mutex_init( &__lock__, NULL ); // pthread用のMutexオブジェクトを初期化
212 #endif
213  }
214 
217  {
218 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
219  // スレッドサポートはしないので特に必何もしない
220 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
221  DeleteCriticalSection( &__lock__ ); // クリティカルセクションオブジェクトを削除
222 #else
223  pthread_mutex_destroy( &__lock__ ); // pthread用のMutexオブジェクトを初期化
224 #endif
225  }
226 
227 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
228 
229  // スレッドサポートはしないので特に必何もしない
230  bool lock( ){ return( true ); }
231  bool unlock( ){ return( true ); }
232  bool try_lock( ){ return( true ); }
233 
234 #else
235 
241  bool lock( )
242  {
243 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
244  EnterCriticalSection( &__lock__ ); // クリティカルセクションオブジェクトをロック
245 #else
246  pthread_mutex_lock( &__lock__ ); // pthread用のMutexオブジェクトをロック
247 #endif
248 
249  return( true );
250  }
251 
252 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
253 
254 
255 
256 
257 
258 
259 
260  bool try_lock( )
261  {
262  // クリティカルセクションオブジェクトのロックが可能かを調べる
263 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
264  return( TryEnterCriticalSection( &__lock__ ) != FALSE );
265 #else
266  return( pthread_mutex_trylock( &__lock__ ) == 0 );
267 #endif
268  }
269 #endif
270 
272  bool unlock( )
273  {
274 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
275  LeaveCriticalSection( &__lock__ ); // クリティカルセクションオブジェクトをアンロック
276 #else
277  pthread_mutex_unlock( &__lock__ ); // pthread用のMutexオブジェクトをアンロック
278 #endif
279 
280  return( true );
281  }
282 
283 #endif
284 };
285 
287 // スレッドグループの終わり
288 
289 template < class MUTEX >
290 class lock_object_table : public ::std::map< ::std::string, MUTEX >
291 {
292 private:
293  typedef ::std::map< ::std::string, MUTEX > base;
294  typedef MUTEX lock_object_type;
295 
296 public:
297  lock_object_table( )
298  {
299  }
300 
301  ~lock_object_table( )
302  {
303  typename base::iterator ite = base::begin( );
304  for( ; ite != base::end( ) ; ++ite )
305  {
306  destroy( ite->second );
307  }
308  base::clear( );
309  }
310 
311 protected:
312  static void destroy( lock_object_type &l )
313  {
314 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
315  // スレッドサポートはしないので特に必何もしない
316 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
317  DeleteCriticalSection( &l ); // クリティカルセクションオブジェクトを削除
318 #else
319  pthread_mutex_destroy( &l ); // pthread用のMutexオブジェクトを初期化
320 #endif
321  }
322 };
323 
327 
328 
363 {
364 protected:
365  ::std::string lock_name_;
366 
367 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
368  typedef char lock_object_type; // スレッドサポートはしないのでダミー変数用意
369 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
370  typedef CRITICAL_SECTION lock_object_type; // Windows用のロックオブジェクト(CRITIFCALSECTIONを利用)
371 #else
372  typedef pthread_mutex_t lock_object_type; // pthreadライブラリでのロックオブジェクト
373 #endif
374 
375  typedef lock_object_table< lock_object_type > lock_table;
376 
377 public:
378  lock_object( ) : lock_name_( "mist default lock object!!" ){ }
379  lock_object( const std::string &name ) : lock_name_( name ){ }
380 
381 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
382 
383  // スレッドサポートはしないので特に必何もしない
384  bool lock( ){ return( true ); }
385  bool unlock( ){ return( true ); }
386 
387 #else
388 
394  bool lock( )
395  {
396  static lock_object_type &__double_lock__ = double_lock_object( );
397 
398  // テーブルの検索でスレッドが衝突しないようにロックする
399  lock( __double_lock__ );
400 
401  lock_table &table = singleton< lock_table >::get_instance( );
402  lock_table::iterator ite = table.find( lock_name_ );
403  if( ite == table.end( ) )
404  {
405  // まだロックオブジェクトを初期化していないので初期化する
406  ::std::pair< lock_table::iterator, bool > p = table.insert( lock_table::value_type( lock_name_, lock_object_type( ) ) );
407  if( p.second )
408  {
409  lock_object_type &obj = p.first->second;
410  initialize( obj );
411 
412  // テーブル検索用のロックを開放する
413  unlock( __double_lock__ );
414 
415  lock( obj );
416  }
417  else
418  {
419  // テーブル検索用のロックを開放する
420  unlock( __double_lock__ );
421 
422  // ロックオブジェクトをテーブルに追加することができませんでした・・・
423  return( false );
424  }
425  }
426  else
427  {
428  // テーブル検索用のロックを開放する
429  unlock( __double_lock__ );
430 
431  // すでに同名のロックオブジェクトが存在するのでそちらをロックする
432  lock( ite->second );
433  }
434 
435  return( true );
436  }
437 
438 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
439 
440 
441 
442 
443 
444 
445 
446  bool try_lock( )
447  {
448  static lock_object_type &__double_lock__ = double_lock_object( );
449 
450  // テーブルの検索でスレッドが衝突しないようにロックする
451  lock( __double_lock__ );
452 
453  lock_table &table = singleton< lock_table >::get_instance( );
454  lock_table::iterator ite = table.find( lock_name_ );
455  if( ite == table.end( ) )
456  {
457  // まだロックオブジェクトを初期化していないので初期化する
458  ::std::pair< lock_table::iterator, bool > p = table.insert( lock_table::value_type( lock_name_, lock_object_type( ) ) );
459  if( p.second )
460  {
461  lock_object_type &obj = p.first->second;
462  initialize( obj );
463 
464  // テーブル検索用のロックを開放する
465  unlock( __double_lock__ );
466 
467  return( try_lock( obj ) );
468  }
469  else
470  {
471  // テーブル検索用のロックを開放する
472  unlock( __double_lock__ );
473 
474  // ロックオブジェクトをテーブルに追加することができませんでした・・・
475  return( false );
476  }
477  }
478  else
479  {
480  // テーブル検索用のロックを開放する
481  unlock( __double_lock__ );
482 
483  // すでに同名のロックオブジェクトが存在するのでそちらをロックする
484  return( try_lock( ite->second ) );
485  }
486  }
487 #endif
488 
490  bool unlock( )
491  {
492  lock_table &table = singleton< lock_table >::get_instance( );
493  lock_table::iterator ite = table.find( lock_name_ );
494  if( ite == table.end( ) )
495  {
496  // 指定されたロックオブジェクトが見つからなかったので何もしない
497  return( false );
498  }
499  else
500  {
501  unlock( ite->second );
502  }
503  return( true );
504  }
505 
506 #endif
507 
508 
509 protected:
511  static lock_object_type &double_lock_object( )
512  {
513  static bool isFirst = true;
514  static lock_object_type __double_lock__;
515  if( isFirst )
516  {
517  isFirst = false;
518  initialize( __double_lock__ );
519  }
520  return( __double_lock__ );
521  }
522 
527  static void initialize( lock_object_type &l )
528  {
529 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
530  // スレッドサポートはしないので特に必何もしない
531 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
532  InitializeCriticalSection( &l ); // クリティカルセクションオブジェクトを初期化
533 #else
534  pthread_mutex_init( &l, NULL ); // pthread用のMutexオブジェクトを初期化
535 #endif
536  }
537 
538 
543  static void lock( lock_object_type &l )
544  {
545 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
546  // スレッドサポートはしないので特に必何もしない
547 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
548  EnterCriticalSection( &l ); // クリティカルセクションオブジェクトをロック
549 #else
550  pthread_mutex_lock( &l ); // pthread用のMutexオブジェクトをロック
551 #endif
552  }
553 
554 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
555 
556 
557 
558 
559 
560 
561 
562 
563 
564  static bool try_lock( lock_object_type &l )
565  {
566  // クリティカルセクションオブジェクトのロックが可能かを調べる
567 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
568  // スレッドサポートはしないので特に必何もしない
569  return( true );
570 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
571  return( TryEnterCriticalSection( &l ) != FALSE );
572 #else
573  return( pthread_mutex_trylock( &l ) == 0 );
574 #endif
575  }
576 #endif
577 
582  static void unlock( lock_object_type &l )
583  {
584 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
585  // スレッドサポートはしないので特に必何もしない
586 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
587  LeaveCriticalSection( &l ); // クリティカルセクションオブジェクトをアンロック
588 #else
589  pthread_mutex_unlock( &l ); // pthread用のMutexオブジェクトをアンロック
590 #endif
591  }
592 };
593 
594 
595 
596 
611 class lock
612 {
613 protected:
615 
616 public:
618  lock( ) : lock_object_( )
619  {
620  lock_object_.lock( );
621  }
622 
623 
625  lock( const std::string &name ) : lock_object_( name )
626  {
627  lock_object_.lock( );
628  }
629 
630 
632  ~lock( )
633  {
634  lock_object_.unlock( );
635  }
636 };
637 
638 
639 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
640 
641 class signal
642 {
643 protected:
644  HANDLE handle_;
645 
646 public:
648  signal( ) : handle_( CreateEvent( NULL, FALSE, FALSE, NULL ) )
649  {
650  }
651 
653  ~signal( )
654  {
655  CloseHandle( handle_ );
656  }
657 
659  bool wait( unsigned long dwMilliseconds = INFINITE )
660  {
661  DWORD ret = WaitForSingleObject( handle_, dwMilliseconds );
662  if( SUCCEEDED( ret ) )
663  {
664  ResetEvent( handle_ );
665  return ( true );
666  }
667  else
668  {
669  return( false );
670  }
671  }
672 
674  void send( )
675  {
676  SetEvent( handle_ );
677  }
678 
680  void reset( )
681  {
682  ResetEvent( handle_ );
683  }
684 };
685 #else
686 class signal
687 {
688 protected:
689  pthread_cond_t cond_;
690  pthread_mutex_t mutex_;
691  volatile bool flag_;
692 
693 public:
695  signal( ) : flag_( false )
696  {
697  pthread_mutex_init( &mutex_, NULL );
698  pthread_cond_init( &cond_, NULL );
699  pthread_mutex_lock ( &mutex_ );
700  }
701 
703  ~signal( )
704  {
705  pthread_cond_destroy( &cond_ );
706  pthread_mutex_destroy( &mutex_ );
707  }
708 
710  bool wait( unsigned long dwMilliseconds = INFINITE )
711  {
712  if( dwMilliseconds == INFINITE )
713  {
714  while( !flag_ )
715  {
716  if( pthread_cond_wait( &cond_, &mutex_ ) == 0 )
717  {
718  break;
719  }
720  }
721  flag_ = false;
722  return( true );
723  }
724  else
725  {
726  timeval now;
727  gettimeofday( &now, NULL );
728 
729  timespec tm;
730  tm.tv_sec = now.tv_sec + static_cast< time_t >( dwMilliseconds / 1000 );
731  tm.tv_nsec = now.tv_usec * 1000 + static_cast< long >( ( dwMilliseconds % 1000 ) * 1000000 );
732 
733  tm.tv_sec += tm.tv_nsec / 1000000000;
734  tm.tv_nsec = tm.tv_nsec % 1000000000;
735 
736  while( !flag_ )
737  {
738  if( pthread_cond_timedwait( &cond_, &mutex_, &tm ) == 0 )
739  {
740  break;
741  }
742  else
743  {
744  return( false );
745  }
746  }
747 
748  flag_ = false;
749  return( true );
750  }
751  }
752 
754  void send( )
755  {
756  flag_ = true;
757  pthread_cond_broadcast( &cond_ );
758  }
759 
761  void reset( )
762  {
763  flag_ = false;
764  }
765 };
766 #endif
767 
768 
777 template < class thread_parameter = thread_dmy_class >
778 class thread : public thread_object
779 {
780 public:
781  typedef unsigned long thread_exit_type;
782 
783 private:
784 
785 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
786  // スレッドサポートはしないので特に必要な変数は無し
787 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
788  HANDLE thread_handle_; // Windows用のスレッドを識別するハンドル
789  unsigned int thread_id_; // Windows用のスレッドを識別するID
790 #else
791  pthread_t thread_id_; // pthreadライブラリでスレッドを識別するID
792  signal finish_; // スレッドの終了待ちを行うシグナル
793  bool joined_; // スレッドに対する pthread_join 処理が終了しているかどうか
794 #endif
795 
796  simple_lock_object exit_; // 終了待ちシグナル
797  thread_exit_type thread_exit_code_; // スレッドの戻り値
798 
799 public:
800 
802  thread_exit_type exit_code( ) const { return( thread_exit_code_ ); }
803 
804 
813  const thread &operator =( const thread &t )
814  {
815 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
816  // スレッドサポートはしない
817 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
818  thread_handle_ = t.thread_handle_;
819  thread_id_ = t.thread_id_;
820 #else
821  thread_id_ = t.thread_id_;
822  joined_ = t.joined_;
823 #endif
824  thread_exit_code_ = t.thread_exit_code_;
825  return( *this );
826  }
827 
828 
838  bool operator ==( const thread &t ) const
839  {
840 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
841  // スレッドサポートはしない
842  return( this == &t );
843 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
844  return( thread_id_ == t.thread_id_ );
845 #else
846  return( pthread_equal( thread_id_, t.thread_id_ ) != 0 );
847 #endif
848  }
849 
850  bool operator !=( const thread &t ) const
851  {
852  return( !( *this == t ) );
853  }
854 
855 
856 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
857  // スレッドサポートはしない
858  thread( const thread &t ) : thread_exit_code_( t.thread_exit_code_ ){ }
859  thread( ) : thread_exit_code_( 0 ){ }
860 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
861  thread( const thread &t ) : thread_handle_( t.thread_handle_ ), thread_id_( t.thread_id_ ), thread_exit_code_( t.thread_exit_code_ ){ }
862  thread( ) : thread_handle_( NULL ), thread_id_( ( unsigned int )-1 ), thread_exit_code_( 0 ){ }
863 #else
864  thread( const thread &t ) : thread_id_( t.thread_id ), joined_( false ), thread_exit_code_( t.thread_exit_code ){ }
865  thread( ) : thread_id_( ( pthread_t ) ( -1 ) ), joined_( false ), thread_exit_code_( 0 ){ }
866 #endif
867 
868  virtual ~thread( )
869  {
870  this->close( );
871  }
872 
873 
879  virtual bool create( )
880  {
881 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
882  // スレッドサポートはしないので直接関数を呼び出す
883  bool ret = true;
884  thread_exit_code_ = thread_function( );
885 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
886  if( thread_handle_ != NULL ) return( false );
887  thread_handle_ = ( HANDLE )_beginthreadex( NULL, 0, map_thread_function, ( void * )this, 0, &thread_id_ );
888  bool ret = thread_handle_ != NULL ? true : false;
889 #else
890  if( thread_id_ != ( pthread_t ) ( -1 ) ) return( false );
891  bool ret = pthread_create( &( thread_id_ ), NULL, map_thread_function, ( void * )this ) == 0 ? true : false;
892  joined_ = false;
893 #endif
894 
895  return ( ret );
896  }
897 
898 
904  virtual bool create_without_thread( )
905  {
906  thread_exit_code_ = thread_function( );
907  return ( true );
908  }
909 
910 
920  virtual bool wait( unsigned long dwMilliseconds = INFINITE )
921  {
922 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
923  // スレッドサポートはしないので何もしない
924  // スレッドかされないため,dwMilliseconds は常に INFINITE 扱いとなる
925  return( true );
926 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
927  DWORD ret = WaitForSingleObject( thread_handle_, dwMilliseconds );
928  return ( ret == WAIT_OBJECT_0 );
929 #else
930  if( dwMilliseconds == INFINITE )
931  {
932  if( pthread_join( thread_id_, NULL ) == 0 )
933  {
934  joined_ = true;
935  return( true );
936  }
937  else
938  {
939  return( false );
940  }
941  }
942  else
943  {
944  if( finish_.wait( dwMilliseconds ) )
945  {
946  if( pthread_join( thread_id_, NULL ) == 0 )
947  {
948  joined_ = true;
949  return( true );
950  }
951  else
952  {
953  return( false );
954  }
955  }
956  else
957  {
958  return( false );
959  }
960  }
961 #endif
962  }
963 
964 
972  virtual bool close( )
973  {
974 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
975  // スレッドサポートはしないので常に true を返す
976  return( true );
977 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
978  if( thread_handle_ != NULL )
979  {
980  // スレッドの完全終了を待機する
981 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
982  while( !exit_.try_lock( ) ){}
983  exit_.unlock( );
984 #endif
985 
986  BOOL ret = CloseHandle( thread_handle_ );
987  thread_handle_ = NULL;
988  return ( ret != 0 );
989  }
990  else
991  {
992  return( true );
993  }
994 #else
995  if( thread_id_ != ( pthread_t ) ( -1 ) )
996  {
997  // スレッドの完全終了を待機する
998  while( !exit_.try_lock( ) ){}
999  exit_.unlock( );
1000 
1001  if( !joined_ )
1002  {
1003  pthread_join( thread_id_, NULL );
1004  }
1005 
1006  thread_id_ = ( pthread_t ) ( -1 );
1007  return( true );
1008  }
1009  else
1010  {
1011  return( true );
1012  }
1013 #endif
1014  }
1015 
1016 
1017 protected:
1025  virtual thread_exit_type thread_function( ) = 0;
1026 
1027 
1028 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
1029  // スレッドサポートはしないので何もしない
1030 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
1031  static unsigned int __stdcall map_thread_function( void *p )
1032  {
1033  thread *obj = static_cast< thread * >( p );
1034  obj->exit_.lock( );
1035  obj->thread_exit_code_ = obj->thread_function( );
1036  obj->exit_.unlock( );
1037  return( 0 );
1038  }
1039 #else
1040  static void *map_thread_function( void *p )
1041  {
1042  thread *obj = static_cast< thread * >( p );
1043  obj->exit_.lock( );
1044  obj->thread_exit_code_ = obj->thread_function( );
1045  obj->exit_.unlock( );
1046  obj->finish_.send( );
1047  return ( NULL );
1048  }
1049 #endif
1050 };
1051 
1052 
1062 template < class Thread >
1063 inline bool do_threads_( Thread *threads, size_t num_threads, unsigned long dwMilliseconds = INFINITE )
1064 {
1065  bool ret = true;
1066  size_t i = 0;
1067 
1068  // スレッドの生成
1069  for( i = 1 ; i < num_threads ; i++ )
1070  {
1071  if( !threads[ i ].create( ) )
1072  {
1073  ret = false;
1074  }
1075  }
1076  if( num_threads > 0 )
1077  {
1078  // 先頭のパラメータのみ実行スレッドで行う
1079  threads[ 0 ].create_without_thread( );
1080  }
1081 
1082  // スレッドの終了待ち
1083  for( i = 1 ; i < num_threads ; i++ )
1084  {
1085  if( !threads[ i ].wait( dwMilliseconds ) )
1086  {
1087  ret = false;
1088  }
1089  }
1090 
1091  // リソースの開放
1092  for( i = 1 ; i < num_threads ; i++ )
1093  {
1094  if( !threads[ i ].close( ) )
1095  {
1096  ret = false;
1097  }
1098  }
1099 
1100  return( ret );
1101 }
1102 
1112 template < class Thread >
1113 inline bool do_threads_( Thread **threads, size_t num_threads, unsigned long dwMilliseconds = INFINITE )
1114 {
1115  bool ret = true;
1116  size_t i = 0;
1117 
1118  // スレッドの生成
1119  for( i = 1 ; i < num_threads ; i++ )
1120  {
1121  if( !threads[ i ]->create( ) )
1122  {
1123  ret = false;
1124  }
1125  }
1126  if( num_threads > 0 )
1127  {
1128  // 先頭のパラメータのみ実行スレッドで行う
1129  threads[ 0 ]->create_without_thread( );
1130  }
1131 
1132  // スレッドの終了待ち
1133  for( i = 1 ; i < num_threads ; i++ )
1134  {
1135  if( !threads[ i ]->wait( dwMilliseconds ) )
1136  {
1137  ret = false;
1138  }
1139  }
1140 
1141  // リソースの開放
1142  for( i = 1 ; i < num_threads ; i++ )
1143  {
1144  if( !threads[ i ]->close( ) )
1145  {
1146  ret = false;
1147  }
1148  }
1149 
1150  return( ret );
1151 }
1152 
1153 
1154 
1164 template < class Thread >
1165 inline bool do_threads( Thread *threads, size_t num_threads, unsigned long dwMilliseconds = INFINITE )
1166 {
1167  bool ret = true;
1168  size_t i = 0;
1169 
1170  // スレッドの生成
1171  for( i = 0 ; i < num_threads ; i++ )
1172  {
1173  if( !threads[ i ].create( ) )
1174  {
1175  ret = false;
1176  }
1177  }
1178 
1179  // スレッドの終了待ち
1180  for( i = 0 ; i < num_threads ; i++ )
1181  {
1182  if( !threads[ i ].wait( dwMilliseconds ) )
1183  {
1184  ret = false;
1185  }
1186  }
1187 
1188  // リソースの開放
1189  for( i = 0 ; i < num_threads ; i++ )
1190  {
1191  if( !threads[ i ].close( ) )
1192  {
1193  ret = false;
1194  }
1195  }
1196 
1197  return( ret );
1198 }
1199 
1200 
1202 // スレッドグループの終わり
1203 
1204 // スレッドを普通の関数形式の呼び出しで簡便に利用するための関数群
1205 namespace __thread_controller__
1206 {
1207 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
1208  inline unsigned long _timeGetTime_( )
1209  {
1210  return( timeGetTime( ) );
1211  }
1212 #else
1213  inline unsigned long _timeGetTime_( )
1214  {
1215  timeval dmy;
1216  gettimeofday( &dmy, NULL );
1217  return( dmy.tv_sec );
1218  }
1219 #endif
1220 
1221  template < class Param, class Functor >
1222  class thread_object_functor : public thread< thread_object_functor< Param, Functor > >
1223  {
1224  public:
1225  typedef thread< thread_object_functor< Param, Functor > > base;
1226  typedef typename base::thread_exit_type thread_exit_type;
1227 
1228  private:
1229  Param &param_;
1230  Functor func_;
1231 
1232  public:
1233  thread_object_functor( Param &p, Functor f ) : param_( p ), func_( f ){ }
1234  virtual ~thread_object_functor( ){ }
1235 
1236  protected:
1237  // 継承した先で必ず実装されるスレッド関数
1238  virtual thread_exit_type thread_function( )
1239  {
1240  func_( param_ );
1241  return( 0 );
1242  }
1243  };
1244 
1245 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
1246  struct __thread_pool_functor__
1247  {
1248  typedef size_t size_type;
1249  typedef ptrdiff_t difference_type;
1250 
1251  virtual void run( size_type id, size_type nthreads ) = 0;
1252 
1253  virtual ~__thread_pool_functor__( ){}
1254  };
1255 
1256  template < class Param, class Functor >
1257  class thread_pool_functor_base : public __thread_pool_functor__
1258  {
1259  private:
1260  Param param_;
1261  Functor func_;
1262 
1263  public:
1264  thread_pool_functor_base( Param p, Functor f ) : param_( p ), func_( f ){ }
1265  virtual ~thread_pool_functor_base( ){}
1266 
1267  protected:
1268  // 継承した先で必ず実装されるスレッド関数
1269  virtual void run( size_type /* id */, size_type /* nthreads */ )
1270  {
1271  func_( param_ );
1272  }
1273  };
1274 
1275  template < class Param1, class Param2, class Functor >
1276  class thread_pool_functor_base2 : public __thread_pool_functor__
1277  {
1278  private:
1279  Param1 param1_;
1280  Param2 param2_;
1281  Functor func_;
1282 
1283  public:
1284  thread_pool_functor_base2( Param1 p1, Param2 p2, Functor f ) : param1_( p1 ), param2_( p2 ), func_( f ){ }
1285  virtual ~thread_pool_functor_base2( ){ }
1286 
1287  protected:
1288  // 継承した先で必ず実装されるスレッド関数
1289  virtual void run( size_type /* id */, size_type /* nthreads */ )
1290  {
1291  func_( param1_, param2_ );
1292  }
1293  };
1294 
1295  template < class Param1, class Param2, class Param3, class Functor >
1296  class thread_pool_functor_base3 : public __thread_pool_functor__
1297  {
1298  private:
1299  Param1 param1_;
1300  Param2 param2_;
1301  Param3 param3_;
1302  Functor func_;
1303 
1304  public:
1305  thread_pool_functor_base3( Param1 p1, Param2 p2, Param3 p3, Functor f ) : param1_( p1 ), param2_( p2 ), param3_( p3 ), func_( f ){ }
1306  virtual ~thread_pool_functor_base3( ){ }
1307 
1308  protected:
1309  // 継承した先で必ず実装されるスレッド関数
1310  virtual void run( size_type /* id */, size_type /* nthreads */ )
1311  {
1312  func_( param1_, param2_, param3_ );
1313  }
1314  };
1315 
1316  template < class Param1, class Param2, class Param3, class Param4, class Functor >
1317  class thread_pool_functor_base4 : public __thread_pool_functor__
1318  {
1319  private:
1320  Param1 param1_;
1321  Param2 param2_;
1322  Param3 param3_;
1323  Param4 param4_;
1324  Functor func_;
1325 
1326  public:
1327  thread_pool_functor_base4( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Functor f ) : param1_( p1 ), param2_( p2 ), param3_( p3 ), param4_( p4 ), func_( f ){ }
1328  virtual ~thread_pool_functor_base4( ){ }
1329 
1330  protected:
1331  // 継承した先で必ず実装されるスレッド関数
1332  virtual void run( size_type /* id */, size_type /* nthreads */ )
1333  {
1334  func_( param1_, param2_, param3_, param4_ );
1335  }
1336  };
1337 
1338 
1339  template < class Functor >
1340  class thread_pool_void_functor_base : public __thread_pool_functor__
1341  {
1342  private:
1343  Functor func_;
1344 
1345  public:
1346  thread_pool_void_functor_base( Functor f ) : func_( f ){ }
1347  virtual ~thread_pool_void_functor_base( ){ }
1348 
1349  protected:
1350  // 継承した先で必ず実装されるスレッド関数
1351  virtual void run( size_type /* id */, size_type /* nthreads */ )
1352  {
1353  func_( );
1354  }
1355  };
1356 
1357  class thread_pool_functor : public thread< thread_pool_functor >
1358  {
1359  public:
1360  typedef thread< thread_pool_functor > base;
1361  typedef base::thread_exit_type thread_exit_type;
1362  typedef size_t size_type;
1363  typedef ptrdiff_t difference_type;
1364 
1365  private:
1366  std::list< __thread_pool_functor__ * > &functors_;
1367  simple_lock_object &lock_;
1368  simple_lock_object suspend_lock_;
1369  simple_lock_object wait_lock_;
1370  bool is_running_;
1371  bool is_end_;
1372  size_type id_;
1373  size_type nthreads_;
1374  signal signal_;
1375 
1376  public:
1377  thread_pool_functor( std::list< __thread_pool_functor__ * > &functors, simple_lock_object &l, size_type id, size_type nthreads )
1378  : functors_( functors ), lock_( l ), is_running_( false ), is_end_( false ), id_( id ), nthreads_( nthreads )
1379  {
1380  // ロックした状態でスタートする
1381  suspend_lock_.lock( );
1382  }
1383 
1384  virtual ~thread_pool_functor( ){ }
1385 
1386  size_type num_jobs( ) const { return( functors_.size( ) ); }
1387  bool is_end( ) const { return( is_end_ ); }
1388 
1389  bool is_suspended( )
1390  {
1391  if( wait_lock_.try_lock( ) )
1392  {
1393  wait_lock_.unlock( );
1394  return( true );
1395  }
1396  else
1397  {
1398  return( false );
1399  }
1400  }
1401 
1402  virtual bool create( )
1403  {
1404  if( base::create( ) )
1405  {
1406  // スレッドの開始まで待機する
1407  while( true )
1408  {
1409  lock_.lock( );
1410  if( is_running_ )
1411  {
1412  lock_.unlock( );
1413  break;
1414  }
1415  else
1416  {
1417  lock_.unlock( );
1418  }
1419  }
1420 
1421  return( true );
1422  }
1423  else
1424  {
1425  return( false );
1426  }
1427  }
1428 
1429  virtual bool close( )
1430  {
1431  lock_.lock( );
1432  // 終了フラグを立ててスレッドを再起動する
1433  is_end_ = true;
1434  this->resume( );
1435  lock_.unlock( );
1436 
1437  // スレッドが正常終了するまで待つ
1438  while( !wait_lock_.try_lock( ) ){}
1439  wait_lock_.unlock( );
1440 
1441  return( base::close( ) );
1442  }
1443 
1444  void resume( )
1445  {
1446  if( is_suspended( ) )
1447  {
1448  suspend_lock_.unlock( );
1449  while( wait_lock_.try_lock( ) )
1450  {
1451  wait_lock_.unlock( );
1452  }
1453  suspend_lock_.lock( );
1454  }
1455  }
1456 
1457  bool wait( unsigned long dwMilliseconds = INFINITE )
1458  {
1459  lock_.lock( );
1460  if( !wait_lock_.try_lock( ) )
1461  {
1462  lock_.unlock( );
1463  return( signal_.wait( dwMilliseconds ) );
1464  }
1465  else
1466  {
1467  wait_lock_.unlock( );
1468  lock_.unlock( );
1469  return( true );
1470  }
1471  }
1472 
1473  protected:
1474  // 継承した先で必ず実装されるスレッド関数
1475  virtual thread_exit_type thread_function( )
1476  {
1477  wait_lock_.lock( );
1478 
1479  lock_.lock( );
1480  is_running_ = true;
1481  lock_.unlock( );
1482 
1483  while( true )
1484  {
1485  lock_.lock( );
1486  if( is_end_ )
1487  {
1488  lock_.unlock( );
1489  break;
1490  }
1491  else if( functors_.empty( ) )
1492  {
1493  // 処理待ちをする
1494  wait_lock_.unlock( );
1495  lock_.unlock( );
1496  signal_.send( );
1497  suspend_lock_.lock( );
1498  signal_.reset( );
1499  wait_lock_.lock( );
1500  suspend_lock_.unlock( );
1501  }
1502  else
1503  {
1504  // キューの先頭からデータを取り出す
1505  __thread_pool_functor__ *f = functors_.front( );
1506  functors_.pop_front( );
1507  lock_.unlock( );
1508 
1509  if( f != NULL )
1510  {
1511  f->run( id_, nthreads_ );
1512  delete f;
1513  }
1514  }
1515  }
1516 
1517  wait_lock_.unlock( );
1518  signal_.send( );
1519 
1520  return( 0 );
1521  }
1522  };
1523 #endif
1524 }
1525 
1526 
1530 
1531 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
1532 
1533 
1534 
1535 
1536 
1537 
1538 
1539 
1540 
1541 
1542 
1543 
1544 
1545 
1546 
1547 
1548 
1549 
1550 
1551 
1552 
1553 
1554 
1555 
1556 
1557 
1558 
1559 
1560 
1561 
1562 
1564 {
1565 public:
1566  typedef size_t size_type;
1567  typedef ptrdiff_t difference_type;
1568 
1569 private:
1570  typedef __thread_controller__::thread_pool_functor thread_pool_functor;
1571  typedef __thread_controller__::__thread_pool_functor__ __thread_pool_functor__;
1572 
1573  std::vector< thread_pool_functor * > threads_;
1574  std::list< __thread_pool_functor__ * > functors_;
1575  simple_lock_object lock_;
1576  bool initialized_;
1577 
1578 public:
1580  thread_pool( ) : initialized_( false )
1581  {
1582  }
1583 
1585  thread_pool( size_type number_of_max_threads ) : initialized_( false )
1586  {
1587  initialize( number_of_max_threads );
1588  }
1589 
1591  virtual ~thread_pool( )
1592  {
1593  uninitialize( );
1594  }
1595 
1602  bool initialize( size_type number_of_max_threads )
1603  {
1604  // 現在実行中のスレッドを全て終了させる
1605  uninitialize( );
1606 
1607  if( number_of_max_threads == 0 )
1608  {
1609  // 1以上を指定する必要あり
1610  return( false );
1611  }
1612 
1613  threads_.resize( number_of_max_threads );
1614 
1615  // スレッドを実行してアイドル状態にする
1616  for( size_type i = 0 ; i < threads_.size( ) ; i++ )
1617  {
1618  threads_[ i ] = new thread_pool_functor( functors_, lock_, i, threads_.size( ) );
1619  threads_[ i ]->create( );
1620  //threads_[ i ]->wait( );
1621  }
1622 
1623  initialized_ = true;
1624 
1625  return( true );
1626  }
1627 
1632  bool uninitialize( )
1633  {
1634  if( initialized_ )
1635  {
1636  for( size_type i = 0 ; i < threads_.size( ) ; i++ )
1637  {
1638  // スレッドのハンドルを閉じる
1639  threads_[ i ]->close( );
1640 
1641  // 使用していたメモリ領域を開放する
1642  delete threads_[ i ];
1643  }
1644 
1645  threads_.clear( );
1646 
1647  // キューに残っているデータを削除する
1648  lock_.lock( );
1649  while( !functors_.empty( ) )
1650  {
1651  __thread_pool_functor__ *f = functors_.front( );
1652  functors_.pop_front( );
1653  delete f;
1654  }
1655  lock_.unlock( );
1656  }
1657 
1658  initialized_ = false;
1659 
1660  return( true );
1661  }
1662 
1671  template < class Functor, class Param >
1672  bool execute( Functor f, Param p )
1673  {
1674  if( threads_.empty( ) || !initialized_ )
1675  {
1676  return( false );
1677  }
1678 
1679  return( exec( new __thread_controller__::thread_pool_functor_base< Param, Functor >( p, f ) ) );
1680  }
1681 
1691  template < class Functor, class Param1, class Param2 >
1692  bool execute( Functor f, Param1 p1, Param2 p2 )
1693  {
1694  if( threads_.empty( ) || !initialized_ )
1695  {
1696  return( false );
1697  }
1698 
1699  return( exec( new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( p1, p2, f ) ) );
1700  }
1701 
1712  template < class Functor, class Param1, class Param2, class Param3 >
1713  bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3 )
1714  {
1715  if( threads_.empty( ) || !initialized_ )
1716  {
1717  return( false );
1718  }
1719 
1720  return( exec( new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( p1, p2, p3, f ) ) );
1721  }
1722 
1734  template < class Functor, class Param1, class Param2, class Param3, class Param4 >
1735  bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3, Param4 p4 )
1736  {
1737  if( threads_.empty( ) || !initialized_ )
1738  {
1739  return( false );
1740  }
1741 
1742  return( exec( new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( p1, p2, p3, p4, f ) ) );
1743  }
1744 
1751  template < class Functor >
1752  bool execute( Functor f )
1753  {
1754  if( threads_.empty( ) || !initialized_ )
1755  {
1756  return( false );
1757  }
1758 
1759  return( exec( new __thread_controller__::thread_pool_void_functor_base< Functor >( f ) ) );
1760  }
1761 
1771  template < class Functor, class Param >
1772  bool executes( Functor f, Param *param, size_t num_threads )
1773  {
1774  if( threads_.empty( ) || !initialized_ )
1775  {
1776  return( false );
1777  }
1778 
1779  // キューに追加する
1780  lock_.lock( );
1781  for( size_type i = 0 ; i < num_threads ; i++ )
1782  {
1783  functors_.push_back( new __thread_controller__::thread_pool_functor_base< Param, Functor >( param[ i ], f ) );
1784  }
1785  lock_.unlock( );
1786 
1787  resume_thread_from_queue( num_threads );
1788 
1789  return( true );
1790  }
1791 
1802  template < class Functor, class Param1, class Param2 >
1803  bool executes( Functor f, Param1 *param1, Param2 *param2, size_t num_threads )
1804  {
1805  if( threads_.empty( ) || !initialized_ )
1806  {
1807  return( false );
1808  }
1809 
1810  // キューに追加する
1811  lock_.lock( );
1812  for( size_type i = 0 ; i < num_threads ; i++ )
1813  {
1814  functors_.push_back( new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( param1[ i ], param2[ i ], f ) );
1815  }
1816  lock_.unlock( );
1817 
1818  resume_thread_from_queue( num_threads );
1819 
1820  return( true );
1821  }
1822 
1834  template < class Functor, class Param1, class Param2, class Param3 >
1835  bool executes( Functor f, Param1 *param1, Param2 *param2, Param3 *param3, size_t num_threads )
1836  {
1837  if( threads_.empty( ) || !initialized_ )
1838  {
1839  return( false );
1840  }
1841 
1842  // キューに追加する
1843  lock_.lock( );
1844  for( size_type i = 0 ; i < num_threads ; i++ )
1845  {
1846  functors_.push_back( new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( param1[ i ], param2[ i ], param3[ i ], f ) );
1847  }
1848  lock_.unlock( );
1849 
1850  resume_thread_from_queue( num_threads );
1851 
1852  return( true );
1853  }
1854 
1867  template < class Functor, class Param1, class Param2, class Param3, class Param4 >
1868  bool executes( Functor f, Param1 *param1, Param2 *param2, Param3 *param3, Param4 *param4, size_t num_threads )
1869  {
1870  if( threads_.empty( ) || !initialized_ )
1871  {
1872  return( false );
1873  }
1874 
1875  // キューに追加する
1876  lock_.lock( );
1877  for( size_type i = 0 ; i < num_threads ; i++ )
1878  {
1879  functors_.push_back( new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( param1[ i ], param2[ i ], param3[ i ], param4[ i ], f ) );
1880  }
1881  lock_.unlock( );
1882 
1883  resume_thread_from_queue( num_threads );
1884 
1885  return( true );
1886  }
1887 
1898  virtual bool wait( unsigned long dwMilliseconds = INFINITE )
1899  {
1900  if( !initialized_ )
1901  {
1902  return( false );
1903  }
1904  else if( threads_.empty( ) )
1905  {
1906  return( false );
1907  }
1908 
1909  unsigned long st = __thread_controller__::_timeGetTime_( );
1910  size_type i = 0;
1911  for( ; i < threads_.size( ) ; i++ )
1912  {
1913  if( !threads_[ i ]->wait( dwMilliseconds ) )
1914  {
1915  break;
1916  }
1917  else if( dwMilliseconds != INFINITE )
1918  {
1919  unsigned long ct = __thread_controller__::_timeGetTime_( );
1920  if( dwMilliseconds <= ct - st )
1921  {
1922  break;
1923  }
1924  else
1925  {
1926  dwMilliseconds -= ct - st;
1927  st = ct;
1928  }
1929  }
1930  }
1931 
1932  return( i == threads_.size( ) );
1933  }
1934 
1935 protected:
1940  bool exec( __thread_controller__::__thread_pool_functor__ *func )
1941  {
1942  // キューに追加する
1943  {
1944  // 排他制御する
1945  lock_.lock( );
1946  functors_.push_back( func );
1947  lock_.unlock( );
1948  }
1949 
1950  resume_thread_from_queue( 1 );
1951 
1952  return( true );
1953  }
1954 
1959  void resume_thread_from_queue( size_type num_threads )
1960  {
1961  size_type count = 0;
1962  for( size_type i = 0 ; i < threads_.size( ) ; i++ )
1963  {
1964  thread_pool_functor &t = *threads_[ i ];
1965 
1966  if( t.is_suspended( ) )
1967  {
1968  // アイドル状態のスレッドがあれば再開する
1969  t.resume( );
1970 
1971  count++;
1972  }
1973 
1974  if( count >= num_threads )
1975  {
1976  break;
1977  }
1978  }
1979  }
1980 };
1981 
1982 
1983 
2010 {
2011 public:
2012  typedef size_t size_type;
2013  typedef ptrdiff_t difference_type;
2014 
2015 private:
2016  __thread_controller__::thread_pool_functor *thread_;
2017  std::list< __thread_controller__::__thread_pool_functor__ * > functors_;
2018  simple_lock_object lock_;
2019 
2020 public:
2022  worker_thread( ) : thread_( NULL )
2023  {
2024  thread_ = new __thread_controller__::thread_pool_functor( functors_, lock_, 0, 1 );
2025  thread_->create( );
2026  //thread_->wait( );
2027  }
2028 
2030  virtual ~worker_thread( )
2031  {
2032  close( );
2033  }
2034 
2036  bool is_suspended( )
2037  {
2038  if( thread_ == NULL )
2039  {
2040  return( true );
2041  }
2042 
2043  return( thread_->is_suspended( ) );
2044  }
2045 
2050  bool close( )
2051  {
2052  if( thread_ == NULL )
2053  {
2054  return( false );
2055  }
2056 
2057  // スレッドのハンドルを閉じる
2058  thread_->close( );
2059 
2060  // 使用していたメモリ領域を開放する
2061  delete thread_;
2062  thread_ = NULL;
2063 
2064  // キューに残っているデータを削除する
2065  lock_.lock( );
2066  while( !functors_.empty( ) )
2067  {
2068  __thread_controller__::__thread_pool_functor__ *f = functors_.front( );
2069  functors_.pop_front( );
2070  delete f;
2071  }
2072  lock_.unlock( );
2073 
2074  return( true );
2075  }
2076 
2085  template < class Functor, class Param >
2086  bool execute( Functor f, Param p )
2087  {
2088  if( thread_ == NULL )
2089  {
2090  return( false );
2091  }
2092 
2093  return( exec( new __thread_controller__::thread_pool_functor_base< Param, Functor >( p, f ) ) );
2094  }
2095 
2096 
2106  template < class Functor, class Param1, class Param2 >
2107  bool execute( Functor f, Param1 p1, Param2 p2 )
2108  {
2109  if( thread_ == NULL )
2110  {
2111  return( false );
2112  }
2113 
2114  return( exec( new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( p1, p2, f ) ) );
2115  }
2116 
2127  template < class Functor, class Param1, class Param2, class Param3 >
2128  bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3 )
2129  {
2130  if( thread_ == NULL )
2131  {
2132  return( false );
2133  }
2134 
2135  return( exec( new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( p1, p2, p3, f ) ) );
2136  }
2137 
2149  template < class Functor, class Param1, class Param2, class Param3, class Param4 >
2150  bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3, Param4 p4 )
2151  {
2152  if( thread_ == NULL )
2153  {
2154  return( false );
2155  }
2156 
2157  return( exec( new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( p1, p2, p3, p4, f ) ) );
2158  }
2159 
2166  template < class Functor >
2167  bool execute( Functor f )
2168  {
2169  if( thread_ == NULL )
2170  {
2171  return( false );
2172  }
2173 
2174  return( exec( new __thread_controller__::thread_pool_void_functor_base< Functor >( f ) ) );
2175  }
2176 
2187  virtual bool wait( unsigned long dwMilliseconds = INFINITE )
2188  {
2189  if( thread_ == NULL )
2190  {
2191  return( true );
2192  }
2193  else
2194  {
2195  return( thread_->wait( dwMilliseconds ) );
2196  }
2197  }
2198 
2199 protected:
2204  bool exec( __thread_controller__::__thread_pool_functor__ *func )
2205  {
2206  // キューに追加する
2207  {
2208  // 排他制御する
2209  lock_.lock( );
2210  functors_.push_back( func );
2211  lock_.unlock( );
2212  }
2213 
2214  // スレッドを再開する
2215  thread_->resume( );
2216 
2217 
2218  return( true );
2219  }
2220 };
2221 #endif
2222 
2225 {
2226 private:
2227  thread_object *thread_;
2228 
2229 public:
2230 
2232  bool create( ){ return( thread_ == NULL ? false : thread_->create( ) ); }
2233 
2234 
2239  bool wait( unsigned long dwMilliseconds = INFINITE ){ return( thread_ == NULL ? false : thread_->wait( dwMilliseconds ) ); }
2240 
2241 
2243  bool close( )
2244  {
2245  if( thread_ == NULL )
2246  {
2247  return( false );
2248  }
2249  bool b = thread_->close( );
2250  delete thread_;
2251  thread_ = NULL;
2252  return( b );
2253  }
2254 
2255 public:
2256  thread_handle( ) : thread_( NULL ){ }
2257  thread_handle( thread_object *t ) : thread_( t ){ }
2258 
2259  const thread_handle &operator =( const thread_handle &t )
2260  {
2261  if( &t != this )
2262  {
2263  thread_ = t.thread_;
2264  }
2265  return( *this );
2266  }
2267 };
2268 
2309 template < class Param, class Functor >
2310 inline thread_handle create_thread( Param &param, Functor f )
2311 {
2312  thread_handle thread_( new __thread_controller__::thread_object_functor< Param, Functor >( param, f ) );
2313  thread_.create( );
2314  return( thread_ );
2315 }
2316 
2324 template < class Param, class Functor >
2325 inline void create_threads( thread_handle *handles, Param *param, size_t num_threads, Functor f )
2326 {
2327  for( size_t i = 0 ; i < num_threads ; i++ )
2328  {
2329  handles[ i ] = thread_handle( new __thread_controller__::thread_object_functor< Param, Functor >( param[ i ], f ) );
2330  handles[ i ].create( );
2331  }
2332 }
2333 
2334 
2344 inline bool close_thread( thread_handle &thread_ ){ return( thread_.close( ) ); }
2345 
2354 inline bool close_threads( thread_handle *handles, size_t num_threads )
2355 {
2356  bool ret = true;
2357  for( size_t i = 0 ; i < num_threads ; i++ )
2358  {
2359  if( !handles[ i ].close( ) )
2360  {
2361  ret = false;
2362  }
2363  }
2364  return( ret );
2365 }
2366 
2367 
2378 inline bool wait_thread( thread_handle &thread_, unsigned long dwMilliseconds = INFINITE ){ return( thread_.wait( dwMilliseconds ) ); }
2379 
2389 inline bool wait_threads( thread_handle *handles, size_t num_threads, unsigned long dwMilliseconds = INFINITE )
2390 {
2391  if( dwMilliseconds == INFINITE )
2392  {
2393  bool ret = true;
2394  for( size_t i = 0 ; i < num_threads ; i++ )
2395  {
2396  if( !handles[ i ].wait( INFINITE ) )
2397  {
2398  ret = false;
2399  }
2400  }
2401  return( ret );
2402  }
2403  else
2404  {
2405  bool ret = true;
2406  for( size_t i = 0 ; i < num_threads ; i++ )
2407  {
2408 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
2409  DWORD st = timeGetTime( );
2410 #else
2411  timeval dmy;
2412  gettimeofday( &dmy, NULL );
2413  unsigned long st = dmy.tv_sec * 1000 + dmy.tv_usec / 1000;
2414 #endif
2415  if( !handles[ i ].wait( dwMilliseconds ) )
2416  {
2417  ret = false;
2418  }
2419 
2420 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
2421  DWORD et = timeGetTime( );
2422 #else
2423  gettimeofday( &dmy, NULL );
2424  unsigned long et = dmy.tv_sec * 1000 + dmy.tv_usec / 1000;
2425 #endif
2426 
2427  if( st + dwMilliseconds <= et )
2428  {
2429  break;
2430  }
2431  else
2432  {
2433  dwMilliseconds -= et - st;
2434  }
2435  }
2436  return( ret );
2437  }
2438 }
2439 
2440 
2450 template < class Param, class Functor >
2451 inline bool do_thread( Param &param, Functor f, unsigned long dwMilliseconds = INFINITE )
2452 {
2453  bool ret = true;
2454 
2455  // スレッドの生成
2456  thread_handle thread_ = create_thread( param, f );
2457 
2458  // スレッドの終了待ち
2459  if( !wait_thread( thread_, dwMilliseconds ) )
2460  {
2461  ret = false;
2462  }
2463 
2464  // リソースの開放
2465  if( !close_thread( thread_ ) )
2466  {
2467  ret = false;
2468  }
2469  return( ret );
2470 }
2471 
2472 
2483 template < class Param, class Functor >
2484 inline bool do_threads( Param *params, size_t num_threads, Functor f, unsigned long dwMilliseconds = INFINITE )
2485 {
2486  bool ret = true;
2487  thread_handle *threads_ = new thread_handle[ num_threads ];
2488 
2489  // スレッドの生成
2490  create_threads( threads_, params, num_threads, f );
2491 
2492  // スレッドの終了待ち
2493  if( !wait_threads( threads_, num_threads, dwMilliseconds ) )
2494  {
2495  ret = false;
2496  }
2497 
2498  // リソースの開放
2499  if( !close_threads( threads_, num_threads ) )
2500  {
2501  ret = false;
2502  }
2503 
2504  delete [] threads_;
2505 
2506  return( ret );
2507 }
2508 
2509 
2511 // スレッドグループの終わり
2512 
2513 
2514 // mist名前空間の終わり
2515 _MIST_END
2516 
2517 
2518 #endif // __INCLUDE_MIST_THREAD__
2519 

Generated on Wed Nov 12 2014 19:44:26 for MIST by doxygen 1.8.1.2