2011-07-30 6 views
2

次のC++スレッドクラスがあり、新しいスレッドインスタンスはすべて、フォームThreadを継承するクラスのオブジェクトとして実装されています。スレッドを開始するには、オブジェクトが作成され、オブジェクトに対してrun()が呼び出されます。 私が直面している問題は、thread_main関数が終了した後、スレッドのCPU使用率が100%に上昇していることです。たとえば、あるオブジェクトがこのクラスを拡張し、thread_mainがprintf ("%s", "Hello World"); return ;である場合、スレッドを開始すると、CPU使用率はマルチコアプロセッサで100%ジャンプします。 私は間違っていますか?終了時に100%CPUを消費するC++スレッドクラスのバグ

class Thread { 
    public: 
    Thread () 
    { 
    } 

    virtual ~Thread () {} 

    /// function to be called after construction to start thread 
    void run () 
    { 
     pthread_create (&pthread_obj_, NULL, &(static_start_routine), this); 
    } 

    /// called by the thread that has created this thread when it has nothing to do 
    /// apart from waiting for this thread to exit 
    void stop () 
    { 
     pthread_join (pthread_obj_, NULL); 
    } 

    protected: 
    /// implement this function in child class. This is sort of the main 
    /// point of control for Thread class and derived classes. 
    /// Exiting this function means the thread is closed 
    virtual void thread_main () = 0; 

    private: 
    pthread_t pthread_obj_; 

    /// The function supplied as argument to pthread_create must be a static function 
    /// and hence the real start of the thread is Thread::thread_main 
    static void * static_start_routine (void * p_thread_subclass_object_) 
    { 
     reinterpret_cast < Thread * >(p_thread_subclass_object_)->thread_main (); 
     return NULL; 
    } 

    }; 

class ClientThread : public Thread 
{ 
public: 
    ClientThread (DebugLogger & r_dbglogger_, const int r_client_id_, const int r_fd_) 
    : (dbglogger_ (r_dbglogger_), client_id_ (r_client_id_), fd_ (r_fd_) 
    {} 

    virtual ~ClientThread () {} 

    void thread_main () 
    { 
    GenericORSRequestStruct t_client_request_; 
    int retval = read (fd_, & t_client_request_, sizeof (GenericORSRequestStruct)) ; 
    // processing code 
    } 
private: 
    DebugLogger & dbglogger_; 
    const int client_id_; 
    const int fd_; 
}; 

// relevant part from "accept" thread 
void ClientReceiver::thread_main () 
{ 
    while (int fd_ = tcp_server_socket_.Accept ()) 
    { 
     client_id_ ++; 
     ClientThread * t_client_thread_ = new CleintThread (dbglogger_, client_id_, fd_) ; 
     t_client_thread_->run (); // starts the thread 
    } 
} 
// so Thread::stop() is not being called anywhere. 
+0

同じオブジェクトに対して 'run()'を何度も呼び出さないのですか? –

+1

なぜあなたは、[既に何万人もの人によって文書化され、テストされ、使用されているものを使用するのではなく、独自のスレッドクラスを作成しています(http://www.boost.org/doc/libs/release/libs /糸/)? – ildjarn

+0

まず、実際の問題はありませんが、reinterpret_castを使用する必要はありません。static_castを使用する必要があります。実際にスレッドを実行している場所にコードを投稿する必要があります。投稿したコードは不完全です。スレッドを実行するためにクラスを実際にどのように使用しているかを知る必要があります。 – Arunmu

答えて

1

提案のカップル...

  • は、ランタイム・ライブラリ(ビザ-VIのprintf)++あなたは、C/Cのスレッドセーフなバージョンにリンクされていることを確認してください。
  • 新しいスレッドを待って、スレッドが実際に実行を終了するまでmain()を戻さないようにしてください。 main()の後にprintf()を呼び出すのは問題があるかもしれません。
  • stop()までスレッドオブジェクトが実際に動作していることを確認してください(親スレッドによって削除されていないなど)。
+0

私は頭の爪に当たったと思います。ここでmain()の後にprintf()を呼び出すと問題があるかもしれません。 –

関連する問題