多线程图像处理中对选入DC的位图保护
我在应用多线程加速图像处理(具体参见图像处理的多线程计算)的过程中,曾遇到过一个线程同步的问题。多线程对图像不同子块进行处理,再合成。结果发现最终不是全部子块都处理成功,有的子块好像没有被处理。而且发现结果图像中哪个子块没有被处理好像是随机发生的,没有处理的子块个数也不固定。检查程序,确信所有的子块都处理了,所以怀疑各个子线程计算子块后,在更新图像时线程同步出了问题。

有一个子图没有处理
在对结果图像进行更新是用到了DC的BitBlt(),多线程计算时对图像数据是进行了保护的。在更新结果图像时,原来是这么写的。
CDC* pSrcDC = Src.GetDC();
CSingleLock sLock(&Src.m_Critical, TRUE);
BOOL ret = m_memDC.BitBlt(SrcX, SrcY, nWidth, nHeight, pSrcDC, SrcX, SrcY, SRCCOPY);
sLock.Unlock();
Src.ReleaseDC(pSrcDC);
m_memDC是设备兼容的内存DC,最后要写到显示设备。Src是计算后的完整图像位图实例,Src.GetDC()和Src.ReleaseDC(pSrcDC)包含了把Src选入和选出pSrcDC的操作。各计算子线程会异步对Src的各个子块进行更新。每次BitBlt()也是对要更新的子块进行操作,写到m_memDC,对BitBlt()也已经添加了保护,按理说不应该有问题的。但是其他地方都检查过了,只有这里值得怀疑。只有更新没有成功,才可能出现这种情况了。试着对整个DC操作加上保护,改成这样:
CSingleLock sLock(&Src.m_Critical, TRUE);
CDC* pSrcDC = Src.GetDC();
BOOL ret = m_memDC.BitBlt(SrcX, SrcY, nWidth, nHeight, pSrcDC, SrcX, SrcY, SRCCOPY);
Src.ReleaseDC(pSrcDC);
sLock.Unlock();
这样一改,结果马上就正确了。按原来的想法,Src是作为只读的源来对m_memDC更新的,而且每次只更新一个子块。如果同时有其他的子线程在对Src进行其他子块的更新,也不是这里BitBlt()所用到的目标子块。按理来说,即使这里不加保护,应该也不会对最后的结果有影响的。而我原来的代码也对BitBlt()加了保护,只是没有把位图选入选出DC的操作保护起来。然而,实际结果却不是这样。也就是说,在一个位图被选入DC了以后,即使这个位图是作为源,还没有被读取的时候,如果其他线程对这个位图进行了修改,写操作,这个修改可能丢失。下次再对m_memDC更新这个修改,由于Src中的这个修改已经丢失,自然结果就不对了。所以对这个位图保护要从被选入DC之前就开始。
难道在把图像选入DC(调用SelectObject())时,是把图像拷贝到DC的?因此如果不对位图在被选入之前进行保护,把图像选出DC时,内容从DC拷贝回到图像,有可能把图像中别的线程更新的部分覆盖了。所以只有在把图像选入DC之前就保护起来,才能保证每个线程选入DC的图像都是最新的,同时保证在对m_memDC更新时,别的线程不能更新Src。不过这样吧内存向DC拷来拷去,似乎从效率上来说不太好吧。具体到底如何,还真不清楚了。如果有了解的朋友,还望告知。
多线程图像处理中对选入DC的位图保护的更多相关文章
- 图像处理中任意核卷积(matlab中conv2函数)的快速实现。
卷积其实是图像处理中最基本的操作,我们常见的一些算法比如:均值模糊.高斯模糊.锐化.Sobel.拉普拉斯.prewitt边缘检测等等一些和领域相关的算法,都可以通过卷积算法实现.只不过由于这些算法的卷 ...
- hdu6003 Problem Buyer 贪心 给定n个区间,以及m个数,求从n个区间中任意选k个区间,满足m个数都能在k个区间中找到一个包含它的区间,如果一个区间包含了x,那么 该区间不能再去包含另一个数,即k>=m。求最小的k。如果不存在这样的k,输出“IMPOSSIBLE!”。
/** 题目:hdu6003 Problem Buyer 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6003 题意:给定n个区间,以及m个数,求从n个区 ...
- paper 119:[转]图像处理中不适定问题-图像建模与反问题处理
图像处理中不适定问题 作者:肖亮博士 发布时间:09-10-25 图像处理中不适定问题(ill posed problem)或称为反问题(inverse Problem)的研究从20世纪末成为国际上的 ...
- zz剖析为什么在多核多线程程序中要慎用volatile关键字?
[摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...
- [原创]纯JS实现网页中多选复选框checkbox和单选radio的美化效果
图片素材: 最终效果图: <html><title> 纯JS实现网页中多选复选框checkbox和单选radio的美化效果</title><head>& ...
- 在多线程环境中使用CoreData
在多线程环境中使用CoreData BY 子非鱼 · 2014 年 10 月 13 日 上回书说道,其实CoreData学起来也没有很复杂,我们其实增删改查都和别的ORM大同小异.但是世界总是很复 ...
- Linux 多线程应用中如何编写安全的信号处理函数
http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...
- JS 获取select(多选下拉)中所选值的示例代码
通过js获取select(多选下拉)中所选值,具体实现如下,有需要的朋友可以参考下,希望对大家有所帮助 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...
- 关于python多线程编程中join()和setDaemon()的一点儿探究
关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的 ...
随机推荐
- 关于 <textarea ></textarea >标签在苹果微信浏览器出现 内阴影
解决方法:(去除浏览器默认的样式元素) textarea { box-shadow:0px 0px 0px rgba(0,0,0,0); -webkit-appearance:none; }
- gridView 单元格绑定不同控件方法
1.主要代码: private void Form3_Load(object sender, EventArgs e) { DataTable dt = new DataTable(); dt.Col ...
- memcached学习总结
一.介绍1.基于libevent的事件处理 libevent是一套跨平台的事件处理接口的封装,能够兼容包括这些操作系统:Windows/Linux/BSD/Solaris 等操作系统的的事件处理.包装 ...
- 【openstack N版】——计算服务nova
一.openstack计算服务nova 1.1nova介绍 Nova是openstack最早的两块模块之一,另一个是对象存储swift.在openstack体系中一个叫做计算节点,一个叫做控制节点.这 ...
- mysql忘掉密码
1. 先杀掉mysqld的进程: service mysql stop 2. 使用skip-grant-tables这个选项启动MySQL: vi /etc/my.cnf 在mysqld 下添加 sk ...
- 【JSON学习之道】js操作JSON
JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧. JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON ...
- jquery及原生javascript对jsonp解决跨域问题实例详解
jquery方式 前端: $.ajax({ url: 'http://m.xxx.tv/goLottery', data: { data: data }, type: 'GET', dataType: ...
- Eclipse-ee 启动Tomcat后浏览器无法访问Tomat,并且Web项目服务部署
环境: Ubuntu 14.04 + Eclipse-ee + Tomcat7 问题: 在Eclipse中建立Server时选择的Tomcat7,Server的运行时选择的时自己安装的Tomcat目 ...
- Eclipse标准版安装J2EE插件
WTP 使用Eclipse IDE for Java EE Developers是非常方便,但是太大,我喜欢按需配置.首先我们来了解什么是WTP. WTP(Web Tools Platform )项目 ...
- Hibernate优缺点
下面就Hibernate优缺点分别进行简单的阐述.1.Hibernate优点:(1)对象/关系数据库映射(Basic O/R Mapping)它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的 ...