C ++线程类中的错误导致它在退出时消耗100%的CPU

时间:2011-07-30 01:31:02

标签: c++ multithreading pthreads

我有以下C ++线程类,所有新线程实例都是作为继承形式为Thread的类的对象实现的。要启动一个线程,就会创建一个对象,然后在该对象上调用run()。 我面临的问题是在thread_main函数退出后,线程的CPU使用率上升到100%。因此,例如,如果一个对象要扩展此类,并且其thread_main只是printf ( "%s", "Hello World" ); return ;,那么启动一个线程将导致CPU使用率在多核处理器上跳跃100%。 我错了什么?

  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.

1 个答案:

答案 0 :(得分:1)

一些建议......

  • 确保链接到线程安全版本的C / C ++运行时库(visa-vi printf)。
  • 还要确保等待新线程并且不让main()返回,直到线程实际执行完毕。在main()之后调用printf()可能会有问题。
  • 确保Thread对象实际上处于活动状态,直到stop()(例如,未被父线程删除)。