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

有一个子图没有处理

在对结果图像进行更新是用到了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. this的相关介绍与用法

    当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是this.因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this,并 ...

  2. 从C#到TypeScript - Generator

    总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...

  3. H5常见的兼容问题及解决

    最近这两天经常遇到一些麻烦的兼容问题,统一整理一下,比较简单也不是特别全面,希望大家多多交流. 几种IE6 bug的解决方法 1)png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.也 ...

  4. BZOJ 1009 :[HNOI2008]GT考试(KPM算法+dp+矩阵快速幂)

    这道到是不用看题解,不过太经典了,早就被剧透一脸了 这道题很像ac自动机上的dp(其实就是) 然后注意到n很大,节点很小,于是就可以用矩阵快速幂优化了 时间复杂度为o(m^3 *log n); 蒟蒻k ...

  5. 【PHP系列】PHP推荐标准之PSR-1,PSR-2

    说起码代码,刚上大学那会,老师就教导我们,要严格,规范的,把代码写好.代码如人,工工整整.提起规范化的代码,从一开始用命令行编辑C语言代码就开始控制,强制自己按照相关的标准来,所以,现在写代码,不规范 ...

  6. SerfJ REST

    SerfJ提供了一个MVC架构,但它不包含任何模型,其主要特点是使用控制器collerlor,通过这些collerlor管理REST请求.可帮助你开发优雅的MVC架构的应用,使用惯例重于配置的思路,无 ...

  7. hibernate动态切换数据源

    起因: 公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还 ...

  8. 了解 : prevent default

    基本了解是阻止事件之前设置好的事件触发,像是angular router ui里的 preventDefault是这样的. 在$stateChange的是后,可以调用preventDefault 来阻 ...

  9. python打印表格式数据,留出正确的空格和段落星号或注释

    python打印表格式数据,留出正确的空格,格式化打出 代码如下: def printPicnic(itemsDict,leftWidth,rightWidth): print('PICNIC ITE ...

  10. 深入理解 JavaScript 异步系列(3)—— ES6 中的 Promise

    第一部分,Promise 加入 ES6 标准 原文地址 http://www.cnblogs.com/wangfupeng1988/p/6515855.html 未经作者允许不得转载! 从 jquer ...