`
kofsky
  • 浏览: 201633 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

问题记录:可变缓冲区问题

 
阅读更多
网络传输存在的一个问题是,当消息发送速度非常快(比如1s发送200个数据包)时,缓冲区可能会填满而导致发送队列后面的数据发送失败
因此试图通过建立可变缓冲区
当数据发送速度非常快时,马上扩充缓冲区容量,使其适应数据的发送数率

通过动态数组来实现一个动态循环队列的数据缓冲区
std::vector<DataItem> *_dataQueue;

调试中发现一个问题,就是从缓冲区取出的数据次序与送入次数不一致性

原因:
首先往缓冲区依次填入数据
数据包所在位置依次为:
前面的表示缓冲区的位置(为方便,从1开始计数),括号里表示发送包的编号

1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8)
此时另外一个线程取出数据包1(1) 2(2) 3(3)发送;
发送完毕后会停止一段时间
此时循环队列位置Position = 4

此时发送线程继续塞入数据,会先填充位置123,此时缓冲区已满
缓冲区数据依次为:
1(9) 2(10) 3(11) 4(4) 5(5) 6(6) 7(7) 8(8)

于是将缓冲区容量由8扩充至12
继续发送数据
依次填充位置9(12) 10(13) 11(14) 12(15)
填充完毕后,开始取数据
由于循环队列位置Position = 4
那么,此时取数据的顺序变为:
4(4) 5(5) 6(6) 7(7) 8(8) 9(12) 10(13) 11(14) 12(15) 1(9) 2(10) 3(11)


而送入缓冲区的数据包次数为:
4(4) 5(5) 6(6) 7(7) 8(8) 1(9) 2(10) 3(11) 9(12) 10(13) 11(14) 12(15)

两者不一致。

根本原因是:填充数据时是以长度为8的队列在循环,但是取数据的时候则是以一个长度为12的循环队列取数据,次序自然不能保证了。


考虑方法:
1.在扩充容量过程中,将position标号前面的数据包依次拷入扩容的空间,使其与填入缓冲区次序一次。
 也就是在扩容的时候
 将缓冲区中的数据做一次部分移动:
移动前: 1(9) 2(10) 3(11) 4(4) 5(5) 6(6) 7(7) 8(8)
 
移动后: 1(-1) 2(-1) 3(-1) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9) 10(10) 11(11) 12(-1)
   (括号里-1表示数据包无效,可以继续放入数据)
 尝试了:速度太慢

2。记录前一次一个缓冲区的大小,先做小队列循环,再做大队列循环。比如说由8扩充至12时,先做一个队列为8的循环,再做一个队列长为12的循环。
  问题是,如果数据速率超快,那么队列长度的变化由8,12,16,32,那么后面的就会覆盖前面的长度。
  又回到根本性的问题:填充数据与取数据的队列长度 不一致。

。。。下班,明天再来想。

还是用方法1解决:
测试代码:
XmlRpcDataBuffer buf;
	for ( int i = 0; i < 7; i++ )
	{
		char s[20];
		sprintf(s,"%d",i);
		std::string pd = s;
		buf.push(pd);
		buf.print();
	}

	std::string data;
	buf.get(data);
	buf.print();
	buf.get(data);
	buf.print();
	buf.get(data);
	buf.print();
	for ( int i = 7; i < 13; i++ )
	{
		char s[20];
		sprintf(s,"%d",i);
		std::string pd = s;
		buf.push(pd);
		buf.print();
	}

	buf.get(data);
	buf.print();
	buf.get(data);
	buf.print();
	buf.get(data);
	buf.print();
	for ( int i = 13; i < 23; i++ )
	{
		char s[20];
		sprintf(s,"%d",i);
		std::string pd = s;
		buf.push(pd);
		buf.print();
	}



结果如下:
命名:缓冲区序号[循环队列队首]发包序号

0[0](0)
1[0](-1)
2[0](-1)
3[0](-1)
4[0](-1)
5[0](-1)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](-1)
3[0](-1)
4[0](-1)
5[0](-1)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](2)
3[0](-1)
4[0](-1)
5[0](-1)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](2)
3[0](3)
4[0](-1)
5[0](-1)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](2)
3[0](3)
4[0](4)
5[0](-1)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](2)
3[0](3)
4[0](4)
5[0](5)
6[0](-1)
7[0](-1)
*************************************
0[0](0)
1[0](1)
2[0](2)
3[0](3)
4[0](4)
5[0](5)
6[0](6)
7[0](-1)
*************************************
0[1](-1)
1[1](1)
2[1](2)
3[1](3)
4[1](4)
5[1](5)
6[1](6)
7[1](-1)
*************************************
0[2](-1)
1[2](-1)
2[2](2)
3[2](3)
4[2](4)
5[2](5)
6[2](6)
7[2](-1)
*************************************
0[3](-1)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](-1)
*************************************
0[3](-1)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
*************************************
0[3](8)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
*************************************
0[3](8)
1[3](9)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
*************************************
0[3](-1)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
8[3](8)
9[3](9)
10[3](10)
11[3](-1)
*************************************
0[3](-1)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
8[3](8)
9[3](9)
10[3](10)
11[3](11)
*************************************
0[3](12)
1[3](-1)
2[3](-1)
3[3](3)
4[3](4)
5[3](5)
6[3](6)
7[3](7)
8[3](8)
9[3](9)
10[3](10)
11[3](11)
*************************************
0[4](12)
1[4](-1)
2[4](-1)
3[4](-1)
4[4](4)
5[4](5)
6[4](6)
7[4](7)
8[4](8)
9[4](9)
10[4](10)
11[4](11)
*************************************
0[5](12)
1[5](-1)
2[5](-1)
3[5](-1)
4[5](-1)
5[5](5)
6[5](6)
7[5](7)
8[5](8)
9[5](9)
10[5](10)
11[5](11)
*************************************
0[6](12)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
*************************************
0[6](12)
1[6](13)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
*************************************
0[6](12)
1[6](13)
2[6](14)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
*************************************
0[6](12)
1[6](13)
2[6](14)
3[6](15)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
*************************************
0[6](-1)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](-1)
*************************************
0[6](-1)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
*************************************
0[6](18)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
*************************************
0[6](18)
1[6](19)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
*************************************
0[6](18)
1[6](19)
2[6](20)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
*************************************
0[6](-1)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
18[6](18)
19[6](19)
20[6](20)
21[6](21)
22[6](-1)
23[6](-1)
24[6](-1)
25[6](-1)
26[6](-1)
*************************************
0[6](-1)
1[6](-1)
2[6](-1)
3[6](-1)
4[6](-1)
5[6](-1)
6[6](6)
7[6](7)
8[6](8)
9[6](9)
10[6](10)
11[6](11)
12[6](12)
13[6](13)
14[6](14)
15[6](15)
16[6](16)
17[6](17)
18[6](18)
19[6](19)
20[6](20)
21[6](21)
22[6](22)
23[6](-1)
24[6](-1)
25[6](-1)
26[6](-1)
*************************************

分享到:
评论

相关推荐

    ORA-06512 数字或值错误,字符缓冲区太小

    Oracle提供了多种数据类型来存储不同长度的字符串,其中`VARCHAR2`是用于存储变长字符串的一种常见类型,最大长度可达4000字节。而当需要存储更大的文本数据时,则通常会使用`CLOB`(Character Large Object)类型。...

    使用信号量实现有限缓冲区的生产者和消费者问题

    消费者则相反,先尝试加count,如果count不大于0,说明有产品可消费,再加mutex取出产品并减少缓冲区占用数。 接着,我们讨论“读写者问题”,这是一个更复杂的问题,主要涉及到读进程和写进程对共享数据的访问。读...

    缓冲区溢出原理.doc

    缓冲区溢出攻击之所以常见,是因为它太常见了,且易于实现,这完全是软件发展史上不可避免的问题。 一、认识缓冲区溢出 缓冲区溢出是一种系统攻击的手段,借助于在程序缓冲区编写超出其长度的代码,造成溢出,从而...

    具有数据恢复功能的缓冲区

    为了解决这个问题,这个特殊的缓冲区引入了数据恢复机制,意味着它能够记录并保护在异常发生前暂存的数据,以便在系统重新启动后能够恢复这些信息,保证数据完整性。 Ini文件是一种简单的文本配置文件格式,常用于...

    OCP实验手册(Linux版本)

    * Varchar2(s):可变长的字符类型,s 表示字符串的长度。 * Char(s):定长的字符类型,s 表示字符串的长度。 * Date:时间类型,表示时间的年月日,没有长度和精度。 2. SQL 命令行编辑: * a[ppend] text:在...

    字符串缓冲区

    字符串缓冲区的另一个应用场景是在文本处理工具和日志记录系统中。例如,当需要输出大量信息时,先将内容写入缓冲区,等到一定条件满足(如缓冲区满或达到特定行数)后再一次性写入文件或输出设备,从而减少系统调用...

    c可变参数用法 命令

    - 通过`vsprintf(buff, fmt, ap)`来格式化可变参数并存储到缓冲区`buff`中。 - 最后调用`va_end(ap)`来清理可变参数列表。 #### 实际项目中的应用 接下来,我们来看看如何在实际项目中调用这个日志记录函数: ```...

    Peoplesoft开发者手册

    - **对可变用途的限制**:使用变量时的注意事项。 - **本地变量的范围**:局部变量的作用域。 - **地方变量的持续时间**:局部变量的有效期。 - **变量和函数**:变量在函数中的使用。 - **运算符**: - **...

    行业分类-设备装置-可变比特率编码装置与方法、编码程序记录媒体.zip

    本压缩包文件“行业分类-设备装置-可变比特率编码装置与方法、编码程序记录媒体.zip”包含了一份关于VBR编码的详细文档——“可变比特率编码装置与方法、编码程序记录媒体.pdf”。接下来,我们将深入探讨VBR编码的...

    易语言简单键盘记录

    这里会解析按键消息,转换成可读的字符,并存储到日志文件或者内存缓冲区中。 3. 数据存储:记录下来的按键信息需要被妥善保存,可能以文本文件的形式存储,以便后续分析或回放。 4. 键盘钩子管理:在不使用键盘...

    Oracle数据库内存优化的讨论与配置

    - **重做日志缓冲区**:记录数据库的所有修改操作,确保事务的持久性和一致性。 #### 内存优化策略 ##### 共享池优化 共享池的优化主要集中在减少SQL解析和提升SQL语句的共享程度上。关键参数包括: - `shared_...

    emacs 中文手册txt版本

    宏是一种记录一系列命令并可重复执行的功能,对于频繁重复的操作非常有用。例如,如果需要对文本进行复杂的格式化处理,可以先录制一组操作作为宏,然后在需要的时候调用它来节省时间。 - **自定义设置**: - `M-x...

    OCP实验手册(Linux版本).pdf

    - **VARCHAR2(s)**: 可变长度的字符类型,s 表示最大长度。 - 示例:`VARCHAR2(50)` 表示最多可以存储50个字符的字符串。 - **CHAR(s)**: 定长的字符类型,s 表示固定长度。 - 示例:`CHAR(10)` 表示一个长度为10...

    frambuffer 中的结构体简单分析

    - 描述:LCD可变参数结构体,存储了用户可以更改的屏幕参数,如分辨率和像素位深度等。 - 用途:允许用户根据需要动态调整屏幕参数。 4. **`struct fb_fix_screeninfo fix`**: - 描述:LCD固定参数结构体,存储...

    操作系统英文教学课件:Chapter 6 Process Synchronization.ppt

    这是一个固定大小的缓冲区数组,定义了一个`BUFFER_SIZE`,比如10个,以及两个索引`in`和`out`表示生产者放入和消费者取出的位置,以及一个`count`变量记录当前缓冲区中的元素数量。生产者进程在`count`等于`BUFFER_...

    binary-encoding:Binary_Encoding将对象编码到缓冲区中。 Binary_Encoding.Record将表ID以及记录的键和值成分编码到缓冲区中

    这可以通过使用字节序(例如大端序或小端序)、固定长度字段、可变长度字段(如变长整数编码)等来实现。 3. **编码过程**:使用这些规则,`Binary_Encoding.Record` 将表ID、键和值逐一编码。表ID可能是一个固定的...

    第章数据库存储技术(“记录”相关文档)共6张.pptx

    对于变长记录,数据库管理系统还需要处理如何有效地存储和检索这些数据,包括压缩、分页、缓冲区管理等技术,以确保高效的数据存取。此外,数据库系统还会提供索引机制,以便快速定位特定的记录,进一步提高查询效率...

    Oracle内存全面分析

    2. 重做日志缓冲区(Redo Log Buffer):存放事务更新操作产生的重做记录,等待写入重做日志文件。 3. 共享池(Shared Pool):存储PL/SQL代码、SQL语句及其解析结果、数据库链接信息等,减少重复解析。 4. Java池(Java ...

Global site tag (gtag.js) - Google Analytics