gpt4 book ai didi

c++ - 如何设计一个产生数据的类和任意数量的消费者类之间的数据交换

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:52 33 4
gpt4 key购买 nike

我尝试在专门针对设计模式/数据交换/类设计的问题中进行搜索,但无济于事。我专门用 C++ 编程,但这主要是一个设计问题,我认为这是一个很普遍的问题。

我想做的是设计至少两个类之间的数据交换,可能更多,如下:

  • 一个类(class)从磁盘读取图像并分享它们
  • 任意数量的类(0+)独立读取和处理这些图像

共享类不应受限于消费者类的存在。不是专家,我能想到的唯一选择是发布-订阅机制或使用共享内存。

此类问题的可能解决方案及其优缺点是什么?

提前致谢

最佳答案

您可以将其实现为经典的生产者-消费者模式。您没有提到生产者是否可以从不同的线程工作,但我会假设多线程功能使这个解决方案更加灵活。

// Not important what this actually is.
class Image
{ };

using ImagePtr = std::shared_ptr<Image>;

// Shared queue which stores currently available images and
// encapsulates synchronization details.
class ImageQueue
{
private:
std::queue<ImagePtr> m_images;
std::mutex m_mutex;
std::condition_variable m_cond;

public:
void PostImage(std::shared_ptr<Image> image)
{
// Lock the queue, push image, notify single thread.
std::unique_lock<std::mutex> lock(m_mutex);
m_images.push(image);
m_cond.notify_one();
}

ImagePtr WaitForImage()
{
// Lock the queue, wait if empty, fetch image and return it.
std::unique_lock<std::mutex> lock(m_mutex);
if (m_images.empty())
{
m_cond.wait(lock, [&m_images]() -> bool { return !m_images.empty(); });
}
assert (!m_images.empty());
auto nextImage = m_images.front();
m_images.pop();
return nextImage;
}
};

// Image producer class, loads images and posts them into the queue.
class ImageProducer
{
private:
ImageQueue* m_queue;

public:
void LoadImage(const char* file)
{
auto image = loadAndInitializeImageObject(file);
m_queue->PostImage(image);
}
};

// Image consumer class, fetches images and processes them.
class ImageConsumer
{
private:
ImageQueue* m_queue;

public:
void ProcessImage()
{
auto image = m_queue->WaitForImage();
processImage(image);
}
};

这是一个非常非常 beta 版本的概念,但它应该能为您提供一个概览。一些注意事项:

  • 当然,应该有一个队列实例。它可以独立实例化并作为构造函数参数(通过指针或引用)传递给两个类,但它也可以是 ImageProducer 的成员。可以提供公共(public)访问器以获取指向它的指针/引用的类 - 选择取决于特定需求。
  • 目前,逻辑不包括处理何时应该结束的明确点。队列可以有一个额外的 bool标志(例如 m_processingActive ,可能包含在 std::atomic<> 中)。该标志将在构造期间初始化为 true,并在生成最后一个图像后由生产者更改为 false。当队列变为非事件状态时,消费者将结束对图像的等待。

可能还有一些额外的改进,有些事情可能会以不同的方式完成,并且可能会更好。但这个基本概念是一个很好的起点(我希望)。


当然,你不限于单个ImageConsumer类(class)。实际处理函数(在我的代码中为 processImage)可以是一个虚函数,它在专门的类中实现。

关于c++ - 如何设计一个产生数据的类和任意数量的消费者类之间的数据交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48538758/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com