簡體   English   中英

lambdas隊列是C ++ 11中工作隊列的一個好設計模式嗎?

[英]Is a queue of lambdas a good design pattern for a work queue in C++11?

我必須創建一個線程安全的工作隊列,它可以在不同的線程中彈出工作,並在工作線程上處理它。 這項工作可能非常通用,所以我在考慮使用帶捕獲的lambdas作為允許這種情況的好方法。 我有以下代碼作為啟動器:

#include <iostream>
#include <vector>
#include <functional> 
typedef std::function<void()> Task;
typedef std::vector<Task> TaskQueue;

class Queue 
{
   public:
    void flush() {
        for (auto it : m_queue) {
            it();
        }
    }
   // will add thread safe locks later.        
    void queue(Task task) {
        m_queue.push_back(task);
    }

private:
    TaskQueue m_queue;
};
Queue q;

class WorkMaker
{
public: 

    WorkMaker(int inA) : m_a(inA) {}

    void MakeWork() {
        q.queue([&]{
            std::cout << this->m_a << std::endl;
        });
    }


private:
    int m_a;
};

int main()
{
  WorkMaker w1(1);
  WorkMaker w2(2);
  w1.MakeWork();
  w2.MakeWork();
  q.flush();
  return 0;
}

這段代碼是否存在固有的無法解決的問題,還是編譯器會對其進行優化? 還是通過復制lambda或只是指向它的指針將lambda傳遞給std::function參數?

編輯:

我想我可以通過使用shared_ptr並將它們傳遞給lambda來解決內存所有權問題。 請考慮以下修改:

typedef std::function<void()> Task;
typedef std::deque<Task> TaskQueue;

class Queue 
{
   public:
    void flush() {
        while (!m_queue.empty()) {
            auto it = m_queue.front();
            m_queue.pop_front();
            it();
        }
    }
   // will add thread safe locks later.        
    void queue(Task task) {
        m_queue.push_back(task);
    }

private:
    TaskQueue m_queue;
};
Queue q;


class WorkMaker : public std::enable_shared_from_this<WorkMaker>
{
public: 

    WorkMaker(int inA) : m_a(inA) {}
    ~WorkMaker() { std::cout << "Destroy " << m_a << std::endl;  }
    void MakeWork() {
        std::shared_ptr<WorkMaker> self = shared_from_this();
        q.queue([self]{
             std::cout << self->m_a << std::endl;
        });
    }
    int m_a;
};

int main()
{
  {
    auto w1 = std::make_shared<WorkMaker>(1);   
    auto w2 = std::make_shared<WorkMaker>(2);    
    w1->MakeWork();
    w2->MakeWork();
  }
  q.flush();
  return 0;
}

我得到了所需的輸出:

1
Destroy 1
2
Destory 2

std::function將創建函數指針,lambda或其引用的任何內容的私有副本。 通常,此副本從std::function對象引用,以便稍后避免進一步復制。

以這種方式使用std::function對象沒有什么特別慢的。 但是,你應該考慮用std::deque替換std::vector

暫無
暫無

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

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