我不擅长数据结构,所以这可能是一个非常愚蠢的问题。我正在寻找一种方法来实现队列+映射的混合行为。
我目前在多线程单一生产者单个消费者流程中使用来自Intel's developer zone的tbb::concurrent_bounded_queue
(记录在www.threadingbuildingblocks.org)。队列具有市场数据报价对象,并且流程的生产者方面实际上是高度时间敏感的,因此我需要的是一个键入市场数据标识符的队列,例如USDCAD,EURUSD。价值点(通过unique_ptr
)到我收到的此密钥的最新市场数据报价。
所以,让我们说我的队列有5个元素用于5个唯一标识符,突然我们得到队列中第3个位置的标识符的更新市场数据报价,然后我只存储最新的值并丢弃我以前的值。所以,基本上我只是将我的unique_ptr移动到这个密钥的新市场数据报价。
它类似于concurrent_bounded_queue<pair<string, unique_ptr<Quote>>>
,但是键在该对的第一个元素上。
我不确定这是否已经在第三方库中可用(可能是tbb本身),或者如果它是标准数据结构,它是什么。
我非常感谢您提供的任何帮助或指导。
感谢。
答案 0 :(得分:0)
首先,观察我们可以轻松写...
int idn_to_index(idn); // map from identifier to contiguous number sequence
...如果在排序的std::map
中使用std::unordered_map
或std::vector
二进制搜索,您自己的逐字符硬编码解析器,则无关紧要。 ..
然后制作人可以:
更新(使用互斥锁)std::vector<unique_ptr<Quote>>
[idn_to_index(idn)]
将索引发布到concurrent_bounded_queue<int>
消费者:
弹出索引
将[index]中std::vector<unique_ptr<Quote>>
的指针与其最后看到的指针数组进行比较,如果它们不同则处理引用
这里的想法是不要避免在队列中具有重复的特定于标识符的索引,而是为了确保那些最旧的索引仍然触发最新引用的处理,并且在数据的数据之前无害地忽略较不陈旧的队列条目真的再次更新。
答案 1 :(得分:0)
TBB提供
concurrent_undordered_map
:没有并发擦除,稳定迭代器,没有元素访问保护; concurrent_hash_map
:具有并发擦除,并发操作使迭代器无效,通过访问器进行每元素访问管理&#39; 所以,如果问题
&#34; It's like it is similar to concurrent_bounded_queue<pair<string, unique_ptr<Quote>>> but is keyed on the first element of the pair
&#34;意味着建议一个相应的并发关联映射容器,这两个容器都在您的服务中。基本上,您必须在同时擦除标识符的能力(hash_map)和跨所有元素(unordered_map)并发遍历的能力之间进行选择。 concurrent_hash_map
还简化了对元素访问的同步,这些元素对您的案例非常有用。
答案 2 :(得分:0)
我能够解决这个问题如下:
我使用queue
库中的hashmap
和tbb
。现在,我在queue
上推送我的唯一标识符,而不是Quote
。我的hashmap
将我的唯一标识符作为键,引用为值
因此,当我收到Quote
时,我会遍历queue
并检查queue
是否包含该标识符,如果是,则插入相应的Quote
直接进入hashmap
,不要在queue
上添加唯一标识符。如果没有,那么我按下queue
上的标识符和hashmap中对应的Quote
。这样可以确保我的queue
始终作为唯一的标识符集,并且我的hashmap
具有该标识符可用的最新Quote
。
在消费者方面,我弹出queue
以获取我的下一个标识符,并从hashmap
获取该标识符的引用。
这非常快。如果我遗漏了任何隐藏的问题,请告诉我。