在 C++11 中,lambda 队列是否是工作队列的良好设计模式
Is a queue of lambdas a good design pattern for a work queue in C++11?
我必须创建一个线程安全的工作队列,它可以在不同的线程中弹出工作,它将在工作线程上处理它。这项工作可能非常通用,所以我在考虑使用带有捕获的 lambda 作为允许这一点的好方法。我有以下代码作为启动器:
#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 传递到 std::function
参数中是否复制了 lambda 或只是指向它的指针?
编辑:
我想我可以通过使用 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
。
相关文章:
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 是否有可以处理方法调用依赖关系的设计模式?
- 在 C++11 中,lambda 队列是否是工作队列的良好设计模式