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

有一个子图没有处理

在对结果图像进行更新是用到了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的位图保护的更多相关文章

  1. 图像处理中任意核卷积(matlab中conv2函数)的快速实现。

    卷积其实是图像处理中最基本的操作,我们常见的一些算法比如:均值模糊.高斯模糊.锐化.Sobel.拉普拉斯.prewitt边缘检测等等一些和领域相关的算法,都可以通过卷积算法实现.只不过由于这些算法的卷 ...

  2. 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个区 ...

  3. paper 119:[转]图像处理中不适定问题-图像建模与反问题处理

    图像处理中不适定问题 作者:肖亮博士 发布时间:09-10-25 图像处理中不适定问题(ill posed problem)或称为反问题(inverse Problem)的研究从20世纪末成为国际上的 ...

  4. zz剖析为什么在多核多线程程序中要慎用volatile关键字?

    [摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...

  5. [原创]纯JS实现网页中多选复选框checkbox和单选radio的美化效果

    图片素材: 最终效果图: <html><title> 纯JS实现网页中多选复选框checkbox和单选radio的美化效果</title><head>& ...

  6. 在多线程环境中使用CoreData

    在多线程环境中使用CoreData BY 子非鱼 · 2014 年 10 月 13 日   上回书说道,其实CoreData学起来也没有很复杂,我们其实增删改查都和别的ORM大同小异.但是世界总是很复 ...

  7. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  8. JS 获取select(多选下拉)中所选值的示例代码

    通过js获取select(多选下拉)中所选值,具体实现如下,有需要的朋友可以参考下,希望对大家有所帮助 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  9. 关于python多线程编程中join()和setDaemon()的一点儿探究

    关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的  ...

随机推荐

  1. 关于 <textarea ></textarea >标签在苹果微信浏览器出现 内阴影

    解决方法:(去除浏览器默认的样式元素) textarea  { box-shadow:0px 0px 0px rgba(0,0,0,0); -webkit-appearance:none; }

  2. gridView 单元格绑定不同控件方法

    1.主要代码: private void Form3_Load(object sender, EventArgs e) { DataTable dt = new DataTable(); dt.Col ...

  3. memcached学习总结

    一.介绍1.基于libevent的事件处理 libevent是一套跨平台的事件处理接口的封装,能够兼容包括这些操作系统:Windows/Linux/BSD/Solaris 等操作系统的的事件处理.包装 ...

  4. 【openstack N版】——计算服务nova

    一.openstack计算服务nova 1.1nova介绍 Nova是openstack最早的两块模块之一,另一个是对象存储swift.在openstack体系中一个叫做计算节点,一个叫做控制节点.这 ...

  5. mysql忘掉密码

    1. 先杀掉mysqld的进程: service mysql stop 2. 使用skip-grant-tables这个选项启动MySQL: vi /etc/my.cnf 在mysqld 下添加 sk ...

  6. 【JSON学习之道】js操作JSON

    JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧. JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON ...

  7. jquery及原生javascript对jsonp解决跨域问题实例详解

    jquery方式 前端: $.ajax({ url: 'http://m.xxx.tv/goLottery', data: { data: data }, type: 'GET', dataType: ...

  8. Eclipse-ee 启动Tomcat后浏览器无法访问Tomat,并且Web项目服务部署

    环境: Ubuntu 14.04 + Eclipse-ee +  Tomcat7 问题: 在Eclipse中建立Server时选择的Tomcat7,Server的运行时选择的时自己安装的Tomcat目 ...

  9. Eclipse标准版安装J2EE插件

    WTP 使用Eclipse IDE for Java EE Developers是非常方便,但是太大,我喜欢按需配置.首先我们来了解什么是WTP. WTP(Web Tools Platform )项目 ...

  10. Hibernate优缺点

    下面就Hibernate优缺点分别进行简单的阐述.1.Hibernate优点:(1)对象/关系数据库映射(Basic O/R Mapping)它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的 ...