【问题标题】:How I can wait until a Win32 ThreadPool is finished with work, with external cancellation?我怎么能等到 Win32 线程池完成工作,外部取消?
【发布时间】:2021-02-24 05:41:45
【问题描述】:

我正在尝试在我的程序中使用 ThreadPool,但我有一个问题。

我需要一个外部停止 - 过去,函数回调用于检查外部停止,现在我必须这样做。

在新的 ThreadPool API 中,我可以使用 CloseThreadpoolCleanupGroupMembers() 并等待所有排队的作业,或者取消挂起的作业并等待执行。但是如果我打电话给CloseThreadpoolCleanupGroupMembers() 并等待所有的,我就无法对外部事件做些什么。

在不调用 this 或类似的阻塞函数的情况下等待所有作业的好方法是什么?

我想,我可以用一个工作计数器来做到这一点 - 已完成并排队,但也许还有另一个好的解决方案?

【问题讨论】:

    标签: c++ winapi threadpool


    【解决方案1】:

    我找到了一个很好的解决方案:在任务中使用线程保存列表,并在列表中的每个添加元素中使用SubmitThreadpoolJob。在这种情况下,您可以在外部停止时清理任务列表并使用另一个取消功能。

    【讨论】:

      【解决方案2】:

      在这种情况下,我会将“线程计算完成”和“外部事件”消息推送到单个线程安全队列中。然后主线程可以不断循环队列并处理队列外的事件。

      enum EventType {
          THREAD_CALCULATION_FINISHED,
          EXTERNAL_EVENT
      };
      
      // you could probably use an atomic-op ring buffer instead
      std::queue<EventType> message_queue;
      std::mutex message_queue_mutex;
      
      // ...
      
      void wait_on_thread_pool() {
          bool stopped = false;
          int thread_counter = NUM_THREADS;
          while (!stopped) {
              message_queue_mutex.lock();
              while (!message_queue.empty()) {
                  EventType e_type = message_queue.front();
                  message_queue.pop();
                  switch (e_type) {
                  case THREAD_CALCULATION_FINISHED:
                      --thread_counter;
                      if (thread_counter == 0) {
                          stopped = true;
                      }
                      break;
                  case EXTERNAL_EVENT:
                      stopped = true;
                      break;
                  }
              }
              message_queue_mutex.unlock();
          }
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-29
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 2011-12-14
      相关资源
      最近更新 更多