我今天早些时候发现boost::circular
缓冲区的迭代器在多线程环境中的行为并不像我预期的那样。(尽管公平地说,它们的行为也与我在单线程程序中的想法不同)。
如果您调用buffer.begin()
并buffer.end()
表示迭代器以用于循环特定的数据序列。如果将更多数据添加到circular_buffer
. end()
显然,如果您在数据更改后再次调用,您会期望得到不同的结果。但令人困惑的是您已经更改的迭代器对象的值。
有没有一种方法可以创建迭代器,使您可以处理循环缓冲区中的一组数据范围,并且即使在处理范围时将其他数据添加到缓冲区也不会更改它们的值?
如果没有,是否有可能适用的首选“非迭代器”模式,或者可能允许这样做的不同容器类?
#include "stdafx.h"
#include <boost\thread.hpp>
#include <boost\thread\thread_time.hpp>
#include <boost\circular_buffer.hpp>
int _tmain(int argc, _TCHAR* argv[])
{
boost::circular_buffer<int> buffer(20);
buffer.push_back(99);
buffer.push_back(99);
buffer.push_back(99);
boost::circular_buffer<int>::const_iterator itBegin = buffer.begin();
boost::circular_buffer<int>::const_iterator itEnd = buffer.end();
int count = itEnd - itBegin;
printf("itEnd - itBegin == %i\n", count); //prints 3
/* another thread (or this one) pushes an item*/
buffer.push_back(99);
/*we check values of begin and end again, they've changed, even though we have not done anything in this thread*/
count = itEnd - itBegin;
printf("itEnd - itBegin == %i\n", count); //prints 4
}
更新以获取对 ronag 的更详细响应我正在寻找生产者消费者类型模型,并且 boost 文档中显示的有界缓冲区示例与我所需要的非常接近。除了以下两个例外。
我需要能够一次从缓冲区中读取多个数据元素,检查它们,这可能不是微不足道的,然后选择要从缓冲区中删除多少项目。
假的例子:试图从一个字符串中处理两个单词 hello 和 world。
读取 1,缓冲区包含 hel,不要从缓冲区中删除字符。-more 产生读取 2,缓冲区包含 hellowo,我发现 'hello' 删除 5 个字符,缓冲区现在有 wo -more 产生读取 3,缓冲区包含 world,处理 'world',删除另外 5 个字符。
读取时我不需要阻塞生产者线程,除非缓冲区已满。