C++ 是否使用唯一的成员变量?

C++ 是否使用唯一的成员变量?,c++,multithreading,c++11,blockingqueue,C++,Multithreading,C++11,Blockingqueue,在C++11/14中,创建阻塞缓冲队列的更好的设计模式是什么,它可以在没有太多alloc/move的情况下高效地使用资源?使用队列 或 Queue,并在实现中隐藏资源管理(有点像stl容器)。注意,第二个想法(队列)被注释掉了。注释掉的版本对堆/堆栈有什么影响?那么如何使用std::unique\u ptr q 我对C++不太好,但是不管版本如何,我真的不能正确地存储内存吗?(推理:非新建/删除->无内存调用) 代码如下: #include <condition_variable>

在C++11/14中,创建阻塞缓冲队列的更好的设计模式是什么,它可以在没有太多alloc/move的情况下高效地使用资源?使用
队列

Queue
,并在实现中隐藏资源管理(有点像stl容器)。注意,第二个想法(队列)被注释掉了。注释掉的版本对堆/堆栈有什么影响?那么如何使用
std::unique\u ptr q

<>我对C++不太好,但是不管版本如何,我真的不能正确地存储内存吗?(推理:非新建/删除->无内存调用)

代码如下:

#include <condition_variable>
#include <mutex>
#include <queue>

template <class T> class Queue {
public:
  Queue(size_t size);

  // push item to _queue if _queue.size() < _size
  // else block
  void push(T item);
  // void push(std::unique_ptr<T> item);

  // pop item if !_queue.empty()
  // else block or return false after timeout
  bool pop(T &item);
  // bool pop(std::unique_ptr<T> &item);

private:
  std::mutex _mutex;
  std::size_t _size;

  std::queue<T> _queue;
  // std::queue<std::unique_ptr<T>> _queue;

  std::condition_variable _condition_full;
  std::condition_variable _condition_empty;
};

struct Workitem {
  size_t idx;
  void *workdetails;
};

void do_work(Queue<std::unique_ptr<Workitem>> &work_q,
             Queue<std::unique_ptr<Workitem>> &write_q,
             struct options_s &opts) {
  std::unique_ptr<Workitem> work;
  while (work_q.pop(work)) {
    // calculation w/ work
    std::unique_ptr<Workitem> res = consume(work, opts);
    write_q.push(std::move(work));
  }
}
void do_write(Queue<std::unique_ptr<Workitem>> &write_q,
              struct options_s &opts) {
  std::unique_ptr<Workitem> work;
  while (write_q.pop(work)) {
    prepare_for_writing(work, opts); // clean item
    write(work);
  }
}

auto w1 = std::thread(do_work, std::ref(work_q), std::ref(write_q),
                      std::ref(options));
auto w2 = std::thread(do_work, std::ref(work_q), std::ref(write_q),
                      std::ref(options));
auto writer = std::thread(do_write, std::ref(write_q), std::ref(options));

int main() {
  Queue<std::unique_ptr<Workitem>> work_q{4};
  Queue<std::unique_ptr<Workitem>> write_q{4};
  // Queue<Workitem> q{4};
  // ??? std::unique_ptr<Queue<Workitem>> q{4} ???

  for (size_t i, ...) { // do many iterations
    std::unique_ptr<Workitem> w{};
    // Workitem w{};

    populate(w, i); // populate work item

    work_q.push(std::move(w));
  }

  w1.join();
  w2.join();
  writer.join();
}
#包括
#包括
#包括
模板类队列{
公众:
队列(大小);
//如果_queue.size()<\u size,则将项目推送到_队列
//else块
无效推送(T项);
//无效推送(标准::唯一项目);
//弹出项目if!\u queue.empty()
//else在超时后阻塞或返回false
bool pop(T和项目);
//bool pop(标准::唯一项目);
私人:
std::mutex\u mutex;
标准::尺寸\u t\u尺寸;
std::queue\u queue;
//std::queue\u queue;
std::条件变量(条件已满);
std::条件变量_条件_为空;
};
结构工作项{
尺寸(idx);;
无效*工作细节;
};
无效工作(排队和工作),
队列和写入,
结构选项(s&opts){
标准:独特的ptr工作;
while(工作){
//计算w/工作
std::unique_ptr res=消耗(工作、选择);
写q.push(标准::移动(工作));
}
}
无效写入(队列和写入),
结构选项(s&opts){
标准:独特的ptr工作;
while(写作(工作)){
准备写作(工作、选择);//清洁物品
写作(工作);
}
}
自动w1=std::thread(做工作,std::ref(工作),std::ref(写工作),
标准::参考(选项));
auto w2=std::thread(做工作,std::ref(工作),std::ref(写工作),
标准::参考(选项));
自动写入器=std::thread(do_write,std::ref(write_q),std::ref(options));
int main(){
排队工作{4};
队列写入_q{4};
//队列q{4};
//?std::唯一的ptr q{4}???
对于(size_t i,…){//进行多次迭代
std::unique_ptr w{};
//工作项w{};
填充(w,i);//填充工作项
工作推送(标准::移动(w));
}
w1.连接();
w2.join();
writer.join();
}
如果有帮助的话,我可以给出实现,我只是不想把所有的东西都弄得乱七八糟,所以我把它漏掉了。注意,队列由线程使用。我使用两个队列来处理多个工作线程和一个写入线程,以便将负载分散到多个核心上

干杯

在C++11/14中,创建阻塞缓冲队列的更好的设计模式是什么,它可以在没有太多alloc/move的情况下高效地使用资源?使用
队列
队列

根据这些标准,
Queue
更好,因为它避免了一层动态分配

注释掉的版本对堆/堆栈有什么影响

堆与堆栈之间实际上没有任何区别。对象在两种变体中都是动态分配的

我真的不能泄漏内存,对吗?(推理:非新建/删除->无内存调用)

你的推理是正确的。您显示的示例代码没有内存泄漏

但是,存在一个裸指针成员变量
Workitem::workdetails
,如果它被误用(如果它曾经拥有所指向的内存),则可能会导致内存泄漏

在C++11/14中,创建阻塞缓冲队列的更好的设计模式是什么,它可以在没有太多alloc/move的情况下高效地使用资源?使用
队列
队列

根据这些标准,
Queue
更好,因为它避免了一层动态分配

注释掉的版本对堆/堆栈有什么影响

堆与堆栈之间实际上没有任何区别。对象在两种变体中都是动态分配的

我真的不能泄漏内存,对吗?(推理:非新建/删除->无内存调用)

你的推理是正确的。您显示的示例代码没有内存泄漏


但是,有一个裸指针成员变量
Workitem::workdetails
,如果它被误用(如果它曾经拥有它指向的内存),可能会导致内存泄漏。

我不知道在这种情况下使用
unique\u ptr
会给您带来什么好处,内部
std::queue
已经将其内部数据存储在堆上。Workdetails可能会泄漏。这不是为了工作,不要担心。我认为,使用线程时,只传递一个智能指针更好。我将添加更多的细节来说明我的意思,理想情况下,您的队列应该是不可知项的。如果需要存储智能指针,请让队列的使用者进行该调用;而不是队列本身。Ex:使用接口库(唯一或共享)存储多态对象是一种逻辑选择,但对于使用队列的代码来说是一种选择;不是排队。编码一个队列,其中项目允许有效的移动概念(对于唯一的ptr,这是必需的),这需要更多的工作,但不管您最终想要什么。您可以完全按照现在所做的方式接受您的参数值。这允许您在需要时移动项目,如果不移动,它们将只是复制。我不知道使用
unique\u ptr
在这种情况下能为您带来什么,内部
std::queue
已经将其内部数据存储在堆上。工作细节可能会泄漏。这不是为了工作,不要担心。我认为,使用线程时,只传递一个智能指针更好。我将添加更多的细节来说明我的意思,理想情况下,您的队列应该是不可知项的。如果需要存储智能指针,请让队列的使用者进行该调用;而不是队列本身。例如:您正在使用接口库(唯一或共享)存储多态对象