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

Bug in C++ thread class that causes it to consume 100% CPU on exit

本文关键字:退出 100% CPU 线程 错误 c++      更新时间:2023-10-16

我有以下c++线程类,所有新的线程实例都是作为继承Thread的类的对象实现的。要启动一个线程,首先创建一个对象,然后在该对象上调用run()。我面临的问题是,一个线程的CPU使用率上升到100%后,thread_main函数退出。因此,例如,如果一个对象要扩展这个类,并且它的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.

几个建议…

  • 确保链接到线程安全版本的C/c++运行库(visa-vi printf)。
  • 还要确保等待新线程,而不是让main()返回,直到线程实际完成执行。在main()之后调用printf()可能会有问题。
  • 确保线程对象在stop()之前实际上是活的(例如,没有被父线程删除)。