Extended Thread Pool(可扩展的线程池)

本文介绍了一个扩展线程池框架ExtendedThreadPool的设计与实现。该框架支持IoC容器Unity,具备线程优先级、动态分配等功能,并通过ITaskItem、ITaskQueue等接口确保任务的有效管理和执行。文中还详细介绍了DefaultTaskQueueController和BoundedTaskQueueController两种队列控制器的具体实现。

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

Extended Thread Pool 的特征

  • IoC 支持(使用了 Unity
  • 扩展队列
  • 扩展任务项
  • 限制了工作线程的最大数量
  • 动态线程分配
  • 线程优先级支持
  • 扩展日志

Extended Thread Pool 的设计

  • ITaskItem 表示任务
  • ITaskQueue 表示任务的队列逻辑
  • ITaskQueueController 表示消费者和生产者之间的通信逻辑(线程安全)
  • WorkThread 表示线程执行
  • ExtendedThreadPool 控制线程的执行

让我们来深入了解每个类:

  • ITaskItem 表示要完成工作
    1.   public   interface  ITaskItem
    2.  {
    3.        ThreadPriority Priority {  get ; }
    4.         void  DoWork();
    5.   }
  • ThreadPriority – WorkThread 的优先级,可以在每个任务中指定
  • ITaskQueue 另一个管理任务队列的接口
    1.      public   interface  ITaskQueue
    2.     {
    3.          int  Count {  get ; }
    4.          void  Enqueue(ITaskItem item);
    5.         ITaskItem Dequeue();
    6.     }
    • ITaskQueueController 提供了消费者和生产者之间的通信逻辑
      1.      public   interface  ITaskQueueController : IDisposable
      2.     {
      3.          int  ConsumersWaiting {  get ; }
      4.          void  Enqueue(ITaskItem item);
      5.         ITaskItem Dequeue();
      6.     }

ITaskQueueController 接口派生了两个队列控制对象:

  • DefaultTaskQueueController
  • BoundedTaskQueueController

Default Task Queue Controller

 

DefaultTaskQueueController 对与 ITaskQueue 是线程安全的封装:

  1. public   class  DefaultTaskQueueController : TaskQueueControllerBase
  2. {
  3.      public  DefaultTaskQueueController(ITaskQueue taskQueue)
  4.         :  base (taskQueue)
  5.     {
  6.     }
  7.     #region Overrides of TaskQueueControllerBase
  8.      public   override   void  Enqueue(ITaskItem item)
  9.     {
  10.          lock  (_locker)
  11.         {
  12.             _taskQueue.Enqueue(item);
  13.              if  (_consumersWaiting > 0)
  14.                 Monitor.PulseAll(_locker);
  15.         }
  16.     }
  17.      public   override  ITaskItem Dequeue()
  18.     {
  19.         ITaskItem taskItem;
  20.          lock  (_locker)
  21.         {
  22.              while  (_taskQueue.Count == 0 && !_isDispose)
  23.             {
  24.                 _consumersWaiting++;
  25.                 Monitor.Wait(_locker);
  26.                 _consumersWaiting--;
  27.             }
  28.              if  (_isDispose)
  29.                  return   null ;
  30.             taskItem = _taskQueue.Dequeue();
  31.         }
  32.          return  taskItem;
  33.     }
  34.     #endregion
  35. }

Bounded Task Queue Controller

BoundedTaskQueueController (线程安全)如果生产者任务或者创建项的任务比消费者的处理速度快,系统将会无限的消耗内存。 BoundedTaskQueueController 允许限制队列的大小来限制生产者的越界。  

  1. public   class  BoundedTaskQueueController : TaskQueueControllerBase
  2. {
  3.      private   readonly   int  _maxTasksCount;
  4.      private   int  _producersWaiting;
  5.      public  BoundedTaskQueueController(ITaskQueue taskQueue,  int  maxTasksCount)
  6.         :  base (taskQueue)
  7.     {
  8.          if  (maxTasksCount < 1)
  9.              throw   new  ArgumentException( "MaxTasksCount should be greater 0" );
  10.         _maxTasksCount = maxTasksCount;
  11.     }
  12.      public   override   void  Enqueue(ITaskItem item)
  13.     {
  14.          lock  (_locker)
  15.         {
  16.              while  (_taskQueue.Count == (_maxTasksCount - 1) && !_isDispose)
  17.             {
  18.                 _producersWaiting++;
  19.                 Monitor.Wait(_locker);
  20.                 _producersWaiting--;
  21.             }
  22.             _taskQueue.Enqueue(item);
  23.              if  (_consumersWaiting > 0)
  24.                 Monitor.PulseAll(_locker);
  25.         }
  26.     }
  27.      public   override  ITaskItem Dequeue()
  28.     {
  29.         ITaskItem taskItem;
  30.          lock  (_locker)
  31.         {
  32.              while  (_taskQueue.Count == 0 && !_isDispose)
  33.             {
  34.                 _consumersWaiting++;
  35.                 Monitor.Wait(_locker);
  36.                 _consumersWaiting--;
  37.             }
  38.              if  (_isDispose)
  39.                  return   null ;
  40.             taskItem = _taskQueue.Dequeue();
  41.              if  (_producersWaiting > 0)
  42.                 Monitor.PulseAll(_locker);
  43.         }
  44.          return  taskItem;
  45.     }
  46. }

Extended Thread Pool

 

ExtendedThreadPool 类管理接口 ITaskQueueController AddTask 方法用来添加任务到任务通道中去。如果最大的线程限制未达到并且 ConsamersWaitin = 0 WorkThread 类的新实例将被创建。  

  1. public   void  AddTask(ITaskItem item)
  2. {
  3.      if  (item.IsNull())
  4.          throw   new  ArgumentNullException( "item" );
  5.      if  (!(Enum.IsDefined( typeof  (ThreadPriority), item.Priority)))
  6.          throw   new  ArgumentException( "priority" );
  7.     TaskQueueController.Enqueue(item);
  8.      if  (IsStartNewWorker())
  9.         CreateWorkThread();
  10. }

Work Thread

 

WorkThread 类,执行任务项和提供日志记录的。  

  1. public   void  Start()
  2. {
  3.      while  (_isRun)
  4.     {
  5.          try
  6.         {
  7.             ITaskItem item = _taskQueueController.Dequeue();
  8.              if  (item.IsNull())
  9.                  continue ;
  10.             DoWork(item);
  11.         }
  12.          catch  (Exception ex)
  13.         {
  14.             _logger.Error(ex.Message);
  15.         }
  16.     }
  17. }

Thread Pool Extensibility

 

ExtendedThreadPool 类提供了 Ioc 支持, ITaskQueueController 接口标记了 Dependency 属性。  

  1. [Dependency]
  2. public  ITaskQueueController TaskQueueController {  private   getset ; }

如果你需要更加强大的任务队列,就必须实现 ITaskQueue 接口,并不需要担心线程安全的问题;也可以创建 ITaskQueueController 。我使用 Unity 来配置 ExtendedThreadPool

 

 

 

 

例子

 

在其中一个项目中,我使用了 multi-threading 进行 MSMQ 交互。 SampleTask 派生了接口 ITaskItem ,可以从项目 CoreDefaultMsmqSample 中了解详情。  

  1. public   void  DoWork()
  2. {
  3.      using  (var transaction =  new  MessageQueueTransaction())
  4.     {
  5.          try
  6.         {
  7.             transaction.Begin();
  8.             Message msmqMessage = 
  9.               _queue.Receive(TimeSpan.FromMilliseconds(500), transaction);
  10.              if  (msmqMessage !=  null )
  11.             {
  12.                 var message = (ExternalMessage) msmqMessage.Body;
  13.                 LogManager.GetLogger(GetType()).Info( "Task has been "  + 
  14.                             "done, info {0}" .FormatWith(message.Data));
  15.                  //Do work
  16.                 Thread.Sleep(1000);
  17.             }
  18.         }
  19.          catch  (Exception ex)
  20.         {
  21.             transaction.Abort();
  22.             LogManager.GetLogger(GetType()).Error(ex.Message);
  23.              return ;
  24.         }
  25.         transaction.Commit();
  26.     }
  27. }

总结

作者考虑到了线程池的可配置性和扩展性,在引用这些代码后,写出的线程应用会非常简洁,且不需要考虑线程之间的复杂操作.如果,你觉得有写模块是你 不需要的,比如日志模块或者IoC模块(这是什么模块我也不清楚),可以自行把代码删除掉,希望原作者会继续他的思路完善这个框架.

1. 核心数据结构模块 // fileinfo.h typedef struct { char name[256]; char path[1024]; off_t size; mode_t permissions; time_t create_time; time_t modify_time; } FileInfo; 2. 静态库实现模块 // fileinfo_static.c int get_file_info_basic(const char *path, FileInfo *info) { struct stat st; if (stat(path, &st) < 0) return -1; // 文件IO操作 // 提取文件名(关键路径处理) const char *base = strrchr(path, '/'); strncpy(info->name, base ? base+1 : path, 255); info->size = st.st_size; // 获取基础属性 return 0; } mode_t permissions; time_t create_time; time_t modify_time; } FileInfo; 3. 动态库实现模块 // fileinfo_dynamic.c int get_file_info_extended(const char *path, FileInfo *info) { struct stat st; if (stat(path, &st) < 0) return -1; // 文件IO操作 strncpy(info->path, path, 1023); // 存储完整路径 info->permissions = st.st_mode & 0777; // 权限掩码 info->create_time = st.st_ctime; info->modify_time = st.st_mtime; return 0; } 4. 多线程处理模块 // main.c void* thread_func(void* arg) { ThreadArg* targ = (ThreadArg*)arg; // 静态库调用 get_file_info_basic(targ->path, &targ->info); // 动态库加载 void* handle = dlopen("./libfileinfo.so", RTLD_LAZY); int (*get_extended)() = dlsym(handle, "get_file_info_extended"); // 动态库调用 get_extended(targ->path, &targ->info); // 同步输出(互斥锁保护) pthread_mutex_lock(&lock); printf("File: %s\n", targ->info.name); /* 属性输出 */ pthread_mutex_unlock(&lock); } int main() { // 创建线程池(每个文件一个线程) for (int i = 0; i < argc-1; i++) { pthread_create(&threads[i], NULL, thread_func, &args[i]); } } 5. 构建系统模块 # Makefile all: static_lib dynamic_lib build_main static_lib: gcc -fPIC -c fileinfo_static.c # 编译静态库对象 ar rcs libfileinfo.a fileinfo_static.o # 打包.a dynamic_lib: gcc -fPIC -shared -o libfileinfo.so fileinfo_dynamic.c # 编译.so build_main: gcc -o file_viewer main.c libfileinfo.a -lpthread -ldl # 链接主
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值