Ошибка в классе потока C ++, который приводит к тому, что он потребляет 100% CPU при выходе - PullRequest
2 голосов
/ 30 июля 2011

У меня есть следующий класс потока C ++, и все новые экземпляры потока реализованы как объекты классов, наследующих форму Thread. Для запуска потока создается объект, а затем вызывается run() для объекта. Проблема, с которой я сталкиваюсь, заключается в том, что загрузка процессора возрастает до 100% после выхода из функции thread_main. Так, например, если объект должен был расширить этот класс, а его thread_main должен был быть просто printf ( "%s", "Hello World" ); return ;, то запуск потока привел бы к тому, что загрузка процессора на многоядерном процессоре выросла бы на 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 Ответ

1 голос
/ 30 июля 2011

Пара предложений ...

  • Убедитесь, что вы ссылаетесь на многопоточную версию библиотеки времени выполнения C / C ++ (visa-vi printf).
  • Также убедитесь, что вы ожидаете новый поток и не позволяете main () вернуться, пока поток фактически не завершит выполнение.Вызов printf () после main () может быть проблематичным.
  • Убедитесь, что объект Thread действительно жив до stop() (например, не удален родительским потоком).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...