现在在Windows下编程,是实时处理海量数据的要求,这时性能有较高的要求。现在的问题是这样的:一个线程A产生数据,累积到一定数量后交给线程B去后续处理(例如写盘什么的),其实是满简单的一个需求了,我就开辟了2个buffer,我的想法是先让A获得第一个buffer的控制权,然后线程B再去等第一buffer控制权,当第一个buffer写满后,线程A释放第一个buffer的控制权,再去获得第二的buffer的控制权。线程B获得第一个buffer的控制权后处理数据,然后释放第一个buffer的控制权,再去等第二个buffer的控制权。以此交替。我可以采用EnterCriticalSection,LeaveCriticalSection来解决这个同步,但是问题是,当A线程对buffer操作时,如果B也在等同一个buffer的控制权,这时候B是不是一直在内核模式和用户模式下切换,耗费资源非常大?有没有其他合理的办法。因为程序中很多对这样的线程,我的目标要求是:
当A线程操作完成后,通知B,B在获得控制权前应该是"休眠"状态,不太耗费资源。对windows下的多线程了解不多,不知道那种同步互斥方式做合适我的应用。谢谢!!!!
当A线程操作完成后,通知B,B在获得控制权前应该是"休眠"状态,不太耗费资源。对windows下的多线程了解不多,不知道那种同步互斥方式做合适我的应用。谢谢!!!!
解决方案 »
- 请教,在IE中如何判断当前鼠标的位置是图片或者link?
- 指针使用
- vc操作xml问题
- 最后70分求助:关于“打印分页”的问题!HELP……
- 图片加载
- ActiveX控件如何使用
- CreateProcess创建出来的程序如何完全隐藏?包括窗口和任务栏
- 为什么在MFC中,CHTTPFile支持SEEK功能,而在关于FTP的文件中,不能SEEK动态定位文件呢
- 谁有vc版的图象放大功能的代码??!!!!
- 串口调试,实现发送编辑框的每行发送,但时要的是每行发送的间隔是可调的
- CListCtrl的风格改成Owner Data,再运行就什么也不显示了
- vc提升WINDOWS7权限是用户可以操作drivers文件夹
最后部分就是
/*
* __kfifo_put - puts some data into the FIFO, no locking version
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these functions.
*/
unsigned int __kfifo_put(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->size - fifo->in + fifo->out);
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, buffer + l, len - l);
fifo->in += len;
return len;
} /*
* __kfifo_get - gets some data from the FIFO, no locking version
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these functions.
*/
unsigned int __kfifo_get(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->in - fifo->out);
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
/* then get the rest (if any) from the beginning of the buffer */
memcpy(buffer + l, fifo->buffer, len - l);
fifo->out += len;
return len;
}
在你贴出的代码中,如果保证一个线程读fifo->out 和另外个线程修改这个值得矛盾呢?
只要尽量减少临界区中所等待的时间与加锁次数,就能提高同步效率。
即使写线程用来计算的读指针的值已经“过期”了,导致的结果也不过是写线程计算出的可用buffer空间比当前实际的小而已,但是绝对不会产生冲突的;反之读线程也一样。另外,临界区实现分两步,首先是利用类似Interlocked的原子操作实现在用户代码空间进入临界区,如果多次尝试不成功,就进入内核态,类似于WaitForSingleObject了
如果想简单,就用一个临界区就是效率最高的;如果想效率更高,就用无锁编程,其实循环缓冲你这种情况也没什么加锁的必要。我才做过相关项目,一个生产者线程不停往缓冲区写,一个线程当缓冲区满一定程度就往磁盘上写。可以明确的告诉你,多个缓冲切换非常的麻烦、非常的容易出错、非常的不易排查问题,解决好同步问题会花费你非常多的时间。