c++ - 是否使用 unique_ptr 成员变量?

标签 c++ multithreading c++11 blockingqueue

创建阻塞缓冲区队列的更好设计模式是什么,它可以在 C++11/14 中有效地使用资源而无需过多的分配/移动?使用 Queue<std::unique_ptr<Workitem>>

Queue<Workitem>并将资源管理隐藏在实现中(有点像 STL 容器)。注意,第二个思路(Queue)被注释掉了。注释掉的版本对堆/堆栈有什么影响?那么使用 std::unique_ptr<Queue<Workitem>> 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();
}

如果有帮助,我可以提供实现,我只是不想弄乱所有内容,所以我将其遗漏了。需要注意的是,队列由线程使用。我使用两个队列用于多个工作线程和一个编写器线程以跨内核分散负载。

干杯

最佳答案

What is a better designpattern for creating a blocking bufferqueue, that uses resources efficiently in C++11/14 without too many allocs/moves? Using Queue<std::unique_ptr<Workitem>> OR Queue<Workitem>

鉴于该标准,Queue<Workitem>更好,因为它避免了一层动态分配。

What are the implications of the commented out version also regarding heap/stack?

堆与栈之间并没有什么区别。对象在两种变体中都是动态分配的。

I can't really leak memory right? (reasonging: not new/delete -> no memoryleaks)

你的推理很有道理。您显示的示例代码没有内存泄漏。

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

关于c++ - 是否使用 unique_ptr 成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44357532/

相关文章:

c++ - 遍历类模板的显式特化

c++ - 原始循环与依赖于索引的循环算法

c++ - 在 C++ 中的 dll 中使用函数?

c++ - 重新排序 vector 数据的有效方法(解释为 3D 数组)

c++ - volatile 复制构造函数有什么用?

multithreading - Node.js 数据处理分布

python - 多处理类型错误 'str'对象不可调用

c# - 发布/订阅架构

c++ - 编译器选项不适用于无序集 C++11 功能

c++ - 在QT中单击菜单时出现段错误