服务端程序线程运行信息管理器

本文介绍了一种服务端程序线程状态管理方法,通过线程专用存储和哈希映射实现线程运行信息的记录与查看,适用于多线程环境中长时间运行任务的状态监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务端程序线程运行信息管理器

 

 

现在的服务端程序都是多线程的并且其中有大量的工作现场,如何知道每一个工作线程都在干什么?

在服务端程序实现时必须考虑到一些工作需要耗时较长,甚至可能因为死锁等原因导致一些线程进入了某个调用就退步出来的情况,这个时候增加远程连接对服务端程序内部工作状态的查看功能就必不可少了;

本文基于一个服务端程序的线程运行信息管理的实现介绍原理并给出代码

首先我们要考虑到对线程运行信息的访问不能有频繁的锁操作,其次该信息应该能够根据使用情况自动的为每个需要运行信息的线程分配的存储空间并且各不关联,同时需要所有线程的运行信息能够进行遍历,这样就可以考虑这样实现:

  1. 线程的运行信息存储在线程专用存储中,这样不但数据各个线程分开避免了锁的开销,而且方便编写程序(就像使用一个单独的成员变量一样);
  2. 每一个线程的运行信息结构的指针和线程的ID关联起来放置到哈希映射表中,这样便于对所有使用了运行信息的线程进行遍历;
  3. 由于运行信息记录的是一个工作线程的工作过程,因此是一个开始工作时记录,结束工作时清除的类似栈的数据信息;

同时因为运行信息只记录需要时间较长并且可能引起无法返回的工作,所以信息量不会很大,因此使用使用一个固定大小的结构定义出来,然后使用 ACE_TSS 模板来自动进行线程专用存储的管理,同时使用 ACE_Hash_Map_Manager 来关联线程ID和运行信息指针;

下面是实现:

复制代码

#pragma  once

// ==================================================================================================
//     概述:
//         线程状态管理器:管理各个线程的运行状态
// ==================================================================================================
struct  StatusManager
{
public :
    
// ----------------------------------------------------------------------------------------------
    
//     概述:
    
//         设置线程的运行信息
    
// ----------------------------------------------------------------------------------------------
     static  ACE_UINT32 SetRunInfo(  const   char   *  RunInfo )
    {
        TASK_RUN_INFO 
&  TaskRunInfo  =  GetInstance( ).GetTaskRunInfo( );
        CHK_EXP_RUN( TaskRunInfo.Number 
>=  MAX_TRI_NUMBER , MAX_TRI_NUMBER );

        TASK_RUN_STATUS 
&  Status  =  TaskRunInfo.Status[ TaskRunInfo.Number ];
        strncpy( Status.String , RunInfo , MAX_TRI_LENGTH 
-   1  );
        ACE_OS::gettimeofday( ).msec( Status.DateTime );
        
return  TaskRunInfo.Number  ++  ;
    }

    
// ----------------------------------------------------------------------------------------------
    
//     概述:
    
//         清除线程的运行信息
    
// ----------------------------------------------------------------------------------------------
     static  ACE_UINT32 ClrRunInfo( ACE_UINT32 RunInfoID )
    {
        TASK_RUN_INFO 
&  TaskRunInfo  =  GetInstance( ).GetTaskRunInfo( );
        CHK_EXP_RUN( TaskRunInfo.Number 
<=  RunInfoID , RunInfoID );
        
        
//     消除指定信息及其以后的信息
         return  TaskRunInfo.Number  =  RunInfoID ;
    }

protected :
    
// ----------------------------------------------------------------------------------------------
    
//     概述:
    
//         定义数据结构和哈希映射类型
    
// ----------------------------------------------------------------------------------------------
     enum  TASK_RUN_INFO_CAPACITY { MAX_TRI_NUMBER  =   255  , MAX_TRI_LENGTH  =   120  };
    
struct  TASK_RUN_STATUS { ACE_UINT64 DateTime;  char  String[ MAX_TRI_LENGTH ]; };
    
struct  TASK_RUN_INFO { ACE_UINT32 Number; TASK_RUN_STATUS Status[ MAX_TRI_NUMBER ]; };
    
struct  S_TASK_RUN_INFO :  public  TASK_RUN_INFO { S_TASK_RUN_INFO( ) { memset(  this  ,  0  , sizeof *   this  ) ); } };
    typedef ACE_Hash_Map_Manager
<  ACE_thread_t , TASK_RUN_INFO  *  , ACE_Thread_Mutex  >  ACE_Hash_Map_Task_Run_Info;

    
// ----------------------------------------------------------------------------------------------
    
//     概述:
    
//         获取线程运行信息结构引用
    
// ----------------------------------------------------------------------------------------------
    inline TASK_RUN_INFO  &  GetTaskRunInfo( )
    {
        ACE_thread_t Thread 
=  ACE_Thread_Manager::instance( ) -> thr_self( );
        S_TASK_RUN_INFO 
*  lpTaskRunInfo  =  TaskRunInfo;
        HashRunInfo.rebind( Thread , lpTaskRunInfo );
        
return   *  lpTaskRunInfo ;
    }

    
// ----------------------------------------------------------------------------------------------
    
//     概述:
    
//         获取状态管理器
    
// ----------------------------------------------------------------------------------------------
     static  StatusManager  &  GetInstance( )
    {
        
static  StatusManager sxStatusManager;
        
return  sxStatusManager;
    }

protected :
    
// ----------------------------------------------------------------------------------------------
    ACE_Hash_Map_Task_Run_Info HashRunInfo;
    ACE_TSS
<  S_TASK_RUN_INFO  >  TaskRunInfo;
};

// ==================================================================================================
//     概述:
//         任务运行信息自动设置清除类
// ==================================================================================================
struct  DPS_Task_Run_Info
{
    inline DPS_Task_Run_Info( 
const   char   *  Format ,  )
    {
        
char  RunInfo[  128  ]  = ""  }; 
        va_list args; va_start( args , Format );
        vsnprintf( RunInfo , 
120  , Format , args );
        m_nTaskRunInfo 
=  StatusManager::SetRunInfo( RunInfo );
    }

    inline 
~ DPS_Task_Run_Info( )
    {
        StatusManager::ClrRunInfo( m_nTaskRunInfo );
    }

    ACE_UINT32 m_nTaskRunInfo;
};

// ==================================================================================================
//     概述:
//         根据编译选项来控制是否需要运行时任务信息
// ==================================================================================================
#ifdef _DPS_DISABLE_TASK_RUN_INFO_
#    define TASK_RUN_INFO( Format ,  )
#    define TASK_RUN_INFO_EX( Name , Format ,  )
#else
#    define TASK_RUN_INFO( Format ,  ) DPS_Task_Run_Info xTaskRunInfo( Format , __VA_ARGS__ )
#    define TASK_RUN_INFO_EX( Name , Format ,  ) DPS_Task_Run_Info Name( Format , __VA_ARGS__ )
#endif
复制代码

 

由于宏中使用了可变参数,所以需要 VC 7.1 及其以上版本才能正常编译,如果不需要可变参数以及信息的格式化功能,那么稍作修改即可使用在 VC6 上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值