【问题标题】:C++ Concurrent Queue pushing by reference or valueC++ 并发队列按引用或值推送
【发布时间】:2020-01-10 22:39:53
【问题描述】:

我有以下代码,其中包括我将一些数据从 C++ 中的 PPL(并发运行时)库推送到并发队列对象。数据会不断更新(针对视频的每一帧),具体操作如下:

short* data;
data = new short[num_samples];
// data gets updated continuously
conQueue->push(data);

我正在初始化队列,如下图:

conQueue = new concurrency::concurrent_queue<short*>;

使用以下库:

#include <ppl.h>
#include <concurrent_queue.h>

我的问题是 - 推送到队列的数据会通过引用或值复制吗?我一直在网上看到混合的 cmets。原因是我从另一个线程中将每个数据从队列中拉出,并且我想确保数据对于它来自的确切帧是准确的(如果通过引用存储,则不是来自某个当前帧) .

我似乎想不出可以测试一下的方法。任何想法将不胜感激 - 谢谢!

【问题讨论】:

  • 您的队列存储指针并且您将指针推向它。它将按值复制。但是除非您将所有权转移给消费者线程并且不在生产者线程中存储数据指针,否则这是非常不安全的。
  • 如果我推送一个指向它的指针,那么它不是通过引用存储吗?指针存储地址而不是实际值对吗?
  • 它存储一个指针的值。
  • 这里的“按引用”和“按值”的术语令人困惑。在这种情况下,您的指针正在被复制 - 所以不,所指向的数据不会被复制。不过,C++ 有一个特殊的引用,所以很多人不会将其称为“通过引用”。您需要小心不要再次访问入队线程上的数据,并记住清理将指针从队列中弹出的线程上的数据。
  • @ChrisPearce 哦,所以你是说它本质上是通过引用存储的?但是,我正在从其他地方的队列中弹出数据并使用它。我不知道你说的第二部分是什么意思

标签: c++ multithreading queue


【解决方案1】:

通过使用new,您创建了一个存在于堆上的数组。一个指针返回给你,它本质上就是你创建的数组在内存中的地址。通过将该地址传递到队列中来复制该地址不会创建该数组的新副本。

因为你正在传递一个指向这个堆分配数据的指针,所以你需要小心何时delete(当你调用new时,一旦你完成了数据,你应该总是delete) .您不希望在将该指针放入队列后立即delete 数组,否则当您尝试将指针从队列中弹出并使用它时,您可能会导致程序崩溃。

为避免此类问题,请确保将数据从队列中弹出的代码在完成后deletes 数组。

我强烈建议通过使用 C++ 标准库中的智能指针类型(例如 std::unique_ptr)来避免更多麻烦,而不是直接处理原始指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多