簡體   English   中英

threadpool c ++實現問題

[英]threadpool c++ implementation questions

在這里這里 ,我們可以看到類似的線程池實現。

我的問題是關於將任務添加到線程池的功能,這些是分別在上面的項目中添加排隊

因為這些看起來很相似我在這里張貼了一塊(來自第二個項目)

auto ThreadPool::enqueue(F&& f, Args&&... args) 
-> std::future<typename std::result_of<F(Args...)>::type>
{
    using return_type = typename std::result_of<F(Args...)>::type;

    auto task = std::make_shared< std::packaged_task<return_type()> >(
        std::bind(std::forward<F>(f), std::forward<Args>(args)...)
    );

    std::future<return_type> res = task->get_future();
    {
        std::unique_lock<std::mutex> lock(queue_mutex);

    // don't allow enqueueing after stopping the pool
        if(stop)
            throw std::runtime_error("enqueue on stopped ThreadPool");

        tasks.emplace([task](){ (*task)(); });
    }
    condition.notify_one();
    return res;
}

容器任務聲明為:

std::queue< std::function<void()> > tasks;

所以我的問題是:

  1. 為什么使用附加包裝器std :: function聲明的任務圍繞任務變量? 為什么任務的隊列沒有被聲明為std :: packaged_task的容器,它也是一個可調用的對象? 我認為任務隊列應包含沒有參數且沒有返回類型的“通用”可調用對象。 所以通過綁定實現刪除參數,額外的包裝器std :: function有助於刪除返回類型,是正確還是不正確? 還有關於shared_ptr的使用 - 是否只是為了避免package_task是可移動類型但std :: function是可復制的沖突?
  2. 對所有線程使用一個共享任務隊列是一個好習慣嗎? 我在看Anthony Williams“C ++ Concurrency in action”,他建議避免這種情況以防止緩存行爭用。 並且他建議使用更高級的技術和兩個級別的隊列 - global和thread_local用於工作者的線程。

如果你還在尋找答案(你大多是自己回答):

  1. 正如你所想的那樣。
  2. 這不是“不好的做法”。 它只會導致性能下降,這不僅是由於緩存行爭用,還因為任務列表上的爭用。

當前的HPC線程池實現主要使用工作竊取調度程序:每個工作程序都有自己的隊列。 工作人員從他/她自己的隊列中拉出並推送工作,直到他完成了自己隊列中的所有任務。 然后它從其他工人竊取任務並執行這些任務。

暫無
暫無

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

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