其中写buffer的线程实时性要求很高,所以任何时候都不希望阻塞这个线程,读buffer的线程没有这样的限制。想了半天,实在没想到好办法
解决方案 »
- 基于UDP网络传输的问题~~
- 求救!!!!!!!!!!!!!!!!!!!!!!!!!!
- 请诸位Windows程序员去看看红旗Linux4.0,谁还敢说Linux不易用!
- 有一组YUV矩阵(400*320)数据矩阵,怎样以最快的速度显示到屏幕上?(Y:U:V=4:1:1)
- 在一个CRichEditCtrl的窗口上加载一副图片,发现内容修改时有抖动,不知道有什么方法避免
- CSocket编程 服务端
- 对excel编程问题
- 各位大虾,怎样用VC制作ActiveX 控件
- 100分!!!!!!!!谁给我答案!!!!!!!!!!!!!
- 关于打印机的问题
- 调试出了一个这样的问题(在线等待)
- 如何从单片机接收实时的数据
思路是参考Linux2.6内核的RCU机制.
所以也就是需要完全拷贝整个buffer,而不是读完就删除,这样比较费内存。
------------------------------------------------
这个是一个比较大的buffer,比如64M(buffer的范围是256K到128M,用户可配置),写数据是顺序写入,可能写满了,可以再从头覆盖写入而读数据可能读取buffer里任何一部分有效的数据
-----------------------------------------------------
读的时间不是很长
不过你的方法应该不能避免临界区冲突,毕竟线程随时都可能被切换
线程A从网络上抓包并写入buffer,线程B是UI线程,用户需要随时看到网络数据包的内容,所以需要从buffer读取数据。因为抓包线程实时性很强,所以不能阻塞(事实证明阻塞并且流量很大时肯定丢包)
如果写线程发现读线程正在读B2,则不对其进行操作(这里没有阻塞写线程)
如果读线程发现写线程正在写B2,则阻塞该线程现在是不想用两个buffer,如果用户配置的内存太大,则很浪费memory
int nReadPos = 0;
int nWritePos = 0;写的时候从buf+nWritePos 处写入,写完成后要更新nWritePos的位置,
读的时候从buf+nReadPos 处读取,读完成后要更新nReadPos的位置,保证nReadPos小于nWritePos就行了。
参考自ACE的ACE_Message_Block
写线程写完以后重新覆盖拷贝!
如果每次都创建copy的话,如果你的buffer比较大,恐怕效率还不及临界区高。
----------------------------------------------
这些原子操作好像只能操作一个变量,或者一个指针,读写操作都不可能对一个变量读写就完成的。
不知道是不是我理解有误
最终的解决方案是采用比较浪费memory的方法,将整个memory分为N个固定长度(长度为网络的MTU,并且在每个块的末尾添加一个指针,如果收到超过MTU的Packet则动态分配一块buffer来存放超过MTU的部分放)的块。另外,还在每个块的尾部设置一个flag,在写之前设置为1,写完成之后设置为2。读线程读取之前判断是否为1,如果是则表示正在写这个块,不再读取这个块。否则设置该flag为3,读取完成之后,再次判断该标志,如果还是3,则表示读取成功,否则表示读取过程中被写线程覆盖过,读取失败。注:对每个块flag的操作均采用 InterLock 的原子操作。这个方案唯一的缺点是比较浪费内存,如果收到的都是较小的Packet的话内存浪费率很高。