qt容器在并发时需要注意的地方
最近用tbb和qt写了一个延时摄影后期控制镜头的工具,主要就是扫描目录下所有图片,按照给定参数截取图片中某区域并另存,模拟镜头摆动。
扫描后的图片路径保存在qlist内,作为只读数据,交由tbb的parellel_for处理。tbb并行对qlist每个元素内的路径对应的图片进行读取,裁剪,另存操作(磁盘是ssd,这个程序在8线程的机器上,可令cpu满负荷)。理想是美好的,现实是残酷的。
前提,qlist(不光qlist了,qt很多数据结构都)实现了copy on write,qlist的索引操作符分为const和非const(const[] 和 [])
首先,界面拥有路径qlist,并按值传递给tbb处理类。
接着,执行过程中遇到了tbb处理线程崩溃的现象,发现从qlist索引出来的路径是无效的QString,调试分析发现,当线程A对qlist索引时,触发了qlist的copy on wirte机制(虽然是按值传递,但仍然与界面的qlist引用同一份数据),机制在没有执行完成的时后,线程B又对qlist进行索引,所以线程B得到的qlist元素是无效的。避免这种情况发生,就要使用const[] 。
个人感想,copy on write机制对于数据平行运算(data parallel)来说属于坑爹的机制,data parallel一个相当重要的前提是,对容器(同一个或不同的)元素的并发读写不会改变容器自身的状态(虽然对于单个元素来说可能存在竞争,但对于容器来说不存在竞争),最简单就例如C语言,对数组元素的读写不会改变数组状态,又例如std::vector,再高级点就例如GPU对render target,memory object,random access view这类对象的并发操作不会改变对象的状态。而qlist只能提供元素只读,同时对元素读写就可能悲剧了。还好,这个工具只会对qlist元素并发读,不需要读写。注意是qlist内的元素,不是qlist容器并发读。
题外话,处理完这个问题后,又出现另一个问题,调试模式下输出文件数少了,最后发现是malloc返回空指针,erron是12,无法分配内存,悲剧啊,图片文件过大了,线程过多了。我处理的图片分辨率是7000*4000,tbb线程有两个图片对象,一个输入一个输出,机器是8线程的cpu,程序是32位,算了一下,2G内存真有可能不够,特别是调试模式,看来要迁移到64位才行。
qt容器在并发时需要注意的地方的更多相关文章
- JAVA同步容器和并发容器
同步容器类 同步容器类的创建 在早期的JDK中,有两种现成的实现,Vector和Hashtable,可以直接new对象获取: 在JDK1.2中,引入了同步封装类,可以由Collections.sync ...
- Java并发——同步容器与并发容器
同步容器类 早期版本的JDK提供的同步容器类为Vector和Hashtable,JDK1.2 提供了Collections.synchronizedXxx等工程方法,将普通的容器继续包装.对每个共有方 ...
- Java并发—同步容器和并发容器
简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector.Ha ...
- Java并发(9)- 从同步容器到并发容器
引言 容器是Java基础类库中使用频率最高的一部分,Java集合包中提供了大量的容器类来帮组我们简化开发,我前面的文章中对Java集合包中的关键容器进行过一个系列的分析,但这些集合类都是非线程安全的, ...
- 【java并发容器】并发容器之CopyOnWriteArrayList
原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...
- java多线程总结-同步容器与并发容器的对比与介绍
1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ...
- Java线程同步类容器和并发容器(四)
同步类容器都是线程安全的,在某些场景下,需要枷锁保护符合操作,最经典ConcurrentModifiicationException,原因是当容器迭代的过程中,被并发的修改了内容. for (Iter ...
- 同步类容器和并发类容器——ConcurrentMap、CopyOnWrite、Queue
一 同步类容器同步类容器都是线程安全的,但在某些场景中可能需要加锁来保证复合操作. 符合操作如:迭代(反复访问元素,遍历完容器中所有元素).跳转(根据指定的顺序找到当前元素的下一个元素).条件运算. ...
- ecshop 秒杀并发时库存会被减到小于0的解决办法
ecshop 秒杀并发时库存会被减到小于0更新库存后,再进行库存检查,如果库存为负数,则执行事务的回滚. begin();//开始一个事物处理开始 $sql = "UPDATE " ...
随机推荐
- PHP session 失效不传递的解决办法
PHP中,session不能传递到下一个页面去,一般有两种情况: 我们先写个php文件:<?=phpinfo()?>, 传到服务器去看看服务器的参数配置. 转到session部分,看到se ...
- 什么是SysWow64
转自 什么是SysWow64 Wow!什么是Wow64 64位的Windows并不是简单地把所有东西都编译成64位就万事大吉的.关于64位的CPU应该做成什么样子,Intel和AMD曾有各自的打算.A ...
- IOS 高级开发 runtime(二)
二.移魂大法 使用runtime还可以交换两个函数.先贴上代码和执行结果. #import <Foundation/Foundation.h> @interface DZLPerson : ...
- C#多线程(一) 入门
本文你会了解如下内容: 1.计算机程序.进程.线程的概念 2.多线程的概念.为什么需要多线程.多线程的好处与坏处 3.C# 线程的一些概念与操作(创建线程.像线程中传递参数.给线程取名.前后台线程.线 ...
- linux 列出安装包内的文件
rpm系列: 1. 文件类型 rpm -qpl xxx.rpm2. 已安装文件 rpm -ql packagename debain系列: dpkg -c xxxx.deb
- PHP pear安装出现 Warning: require_once(Structures/Graph.php)...错误
今天在WINDOWS安装pear,一路无阻很顺利安装完成,接着想安装下pear email包来玩下,但接下来却报: Warning: require_once(Structures/Graph.php ...
- spring定时器用Annotation兑现
spring定时器用Annotation实现 0人收藏此文章, 我要收藏发表于3个月前 , 已有46次阅读 共0个评论 1.ApplicationContext.xml配置 a).需要在xmlns里面 ...
- eclipse下使用maven配置库托管jar包
1.项目是通过maven配置库托管jar包 首先要保证maven配置库中有相应的jar包才能通过这个方法来添加jar包.maven的有点就是把要用到的jar包统一放在一个配置库中,在某个项目需要用到这 ...
- 【BZOJ3270】【高斯消元】博物馆
Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆.这座博物馆有着特别的样式.它包含由m条走廊连接的n间房间,并且满足可以从任何一 ...
- python 自动化之路 day 04.1 python内置函数
总结一下内置函数,Build-in Function. 一.数学运算类 abs(x) 求绝对值 complex([real[, imag]]) 创建一个复数 divmod(a, b) 分别取商和余数注 ...