簡體   English   中英

C ++中的線程池設計

[英]thread pool design in C++

我不確定如何以任何方式在這個論壇中提出這個問題,並希望能得到一些投入。

我正在為我的項目編寫線程池。 我有以下設計。

  1. 我正在維護線程std::vector<ThreadWrapper <threadFuncParam>* > m_vecThreads;

  2. 並將其推入列表m_vecThreads.push_back(pThreadWrapper);

  3. 當新請求到來時,我正在如下線程池中

     if(!m_vecThreads.empty() ) { ThreadWrapper <threadFuncParam>* pWrapper = m_vecThreads.back(); m_vecThreads.pop_back(); //... Awake threadd } 
  4. 線程作業完成后,將其推回到線程池中。

現在,當gracefull關閉時,我已經使用上面的設計從現在開始優雅地停止線程了。我面臨的問題是,如何在請求容器中停止從向量容器中彈出的線程,而在向量中彈出請求,因此我丟失了指針,直到服務完成為止。 我能做些更好的事情還是可以處理這種情況,例如地圖或標准C ++支持的其他容器?

另一個問題是

在關機期間,在我的情況下,我有一個場景線程正在處理數據庫,這可能需要花費一些時間,因此我無法等待它完成,並且我想向正在處理線程的未決請求發送答復給客戶端,並且我將要殺死這個值是不好的。

謝謝!

如果您仍需要訪問從池中傳出的內容,則應將這些項目存儲在“使用過的”容器中。
但是,此時,您正在共享指針,因此您應該使用shared_ptr並傳遞weak_ptr,以便也可以刪除線程,並且用戶沒有懸空的指針。

最適合使用過的物品的硬幣容器是一套,因此可以輕松找到並刪除返回的線程。

要解決您的第一個問題,請將其推入另一個向量,例如m_vecBusyThreads ,完成后,將其取下(請注意,您必須具有某種機制來搜索完成的線程)。

對於第二個問題,最干凈的解決方案是加入每個線程,直到它“關閉”為止,任何其他方法都可能導致一些不良后果(例如,例如,如果它正在連接到db等)。容器,遍歷每個容器,然后遍歷每個空閑容器,關閉並加入每個線程。 然后返回到繁忙的容器並嘗試加入每個線程。 這可能會給繁忙的線程騰出一些時間來徹底關閉它們。

boost :: threads支持這種中斷點的概念,其思想是您可以在任何這些點處中斷線程,但是某些調用是不可中斷的(通常是阻塞調用),您需要找到停止每種類型的最佳方法(例如,讀取的套接字可能是發送虛擬數據包等)

我已經用C完成了,所以解決方案不是“ C ++”式的,但是我使用的是兩個數組:一個包含線程,另一個包含使用/未使用(〜布爾值)的表示。

我會是這樣的:

pthread_t[INITIAL_SIZE] thread_pool;
boolean[INITIAL_SIZE] threads_availability;
int first_available = 0;

pthread_t * get_thread() {
   int ind = 0;
   if (first_available<=INITIAL_SIZE) {
      ind = first_available;
      // find the next available spot
      for (first_available; first_available < INITIAL_SIZE && threads_availability[first_available]; first_available++);
      threads_availability[ind] = 0;

      return thread_pool[ind];
   }
}

void put_thread(pthread_t* thethread)
{
    int i = 0;
    pthread_t *it = thread_pool;
    while (!pthread_equals(it, thethread)) {
        it++;
        i++;
    }
    thread_availability[i] = 1;
}

請記住,這是偽代碼,這不是最佳選擇。 但這是一個主意。

這不是您的問題的直接答案,因為其他人已經回答了您的原始問題。

我只是想說您可以研究boost :: asio和/或boost :: thread。 我可能會去使用boost :: asio,因為它具有您需要進行所有基於計時器等的異步操作所需的一切。 您可以使用shared_ptr和boost :: enable_shared_from_this來使您的“工作”完成工作后自動銷毀。

例:

boost::shared_ptr<async_job> aj( new async_job(
   io_, boost::bind(&my_job::handle_completion, shared_from_this(), _1, _2)));

此代碼將在線程池上執行您的自定義async_job(io_是boost :: asio :: io_service)。 當async_job完成並在其上調用handle_completion時,您的“ my_job”實例將被自動銷毀。 或者,如果再次在handle_completion中使用shared_from_this(),則可以啟用它。

亞歷克斯(HTH)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM