一种自适应轻量级动态混合数据竞争检测方法
技术领域
本发明属于软件测试
技术领域
,具体涉及到并发程序数据竞争检测问题,提出了一种自适应轻量级动态混合数据竞争检测方法。背景技术
多线程程序在现代程序设计中无处不在,因其可以显著提高系统计算效率、性能等优点得到了广泛的应用,但是由于线程交错执行使得许多并发缺陷难以发现,可能会导致并发程序运行结果正确性或者直接导致系统崩溃。并发程序缺陷检测在并发程序研究中有着重要地位,尤其数据竞争问题在常见的并发缺陷中占比较大,因此如何准确高效地检测数据竞争缺陷,成为提高多线程程序可靠性和安全性急需解决的问题。
为了尽可能多检测数据竞争错误,国内外众多学者致力于数据竞争动态检测技术研究,在不影响程序运行结果正确性情况下以期能够以低检测开销方式尽可能多的检测出数据竞争。动态数据竞争缺陷检测技术主要通过收集被测程序动态执行过程中的相关访问信息,进而判断哪些访问操作构成数据竞争,但是由于线程调度具有不确定性,导致收集到的相关信息不完整,存在漏报和误报情况且该技术会消耗大量内存资源。为此本发明提出了一种自适应轻量级动态混合数据竞争检测方法,该方法以低执行开销高覆盖率的方式准确有效地检测数据竞争。
发明内容
动态数据竞争检测技术,其一主要是将收集到的各线程对共享变量的读写访问信息利用Happens-berfore去验证是否存在并发访问,其二主要是利用锁信息去验证共享变量在访问过程中是否受到锁保护,其三是综合利用这两种方法去检测数据竞争。在使用动态数据竞争检测过程中,目标是使检测准确度尽可能提高,而检测时间和内存开销尽可能降低。
本发明为一种自适应轻量级动态混合数据竞争检测方法,如图1所示,该方法的特征包括以下步骤:
步骤一:针对一个Java并发程序P,在不影响P动态执行过程中,动态数据竞争检测器为每个共享变量x分别维护两个长度为Q_LEN=6的读队列RCx和写队列WCx,RCx和WCx均采用先入先出原则以缓存机制存储各线程对x的读访问信息和写访问信息,访问信息以<epoch,LockSet>形式存放,用来表示线程t的线程编号、访问时间戳和当前线程所持有的锁集合,其中epoch表示为[email protected],意为线程t的当前时间戳为c;
步骤二:当线程t对x进行访问,判断当前是否为读访问,如果不为读访问则进入步骤五;否则首先判断当前x是否已经处于读共享状态,如果是读共享状态则更新读向量时钟Rx为线程t的时钟向量VCt;否则去判断t当前读访问与RCx最后一个元素存放的读访问是否构成并发访问状态,如果是则动态数据竞争检测器自动切换为读向量时钟Rx来记录读访问历史,进入步骤三;
步骤三:遍历并分析WCx中线程u对x的历史访问信息直到最后一个元素,即如果WCx[u]中线程u的时间戳与当前线程t的时间戳VCt[u]不满足Happens-before关系,且t目前获得的锁集与WCx[u].LockSet交集为空集,则报告写-读类型数据竞争错误,进入步骤四;
步骤四:判断RCx最后一个元素的epoch值与t的epoch值是否相等,如果相等则更新最后一个元素的LockSet集合;否则判断是否为满队,如果是满队状态则删除队首元素并将当前的访问信息加入到RCx中,否则直接将当前访问信息加入到RCx;
步骤五:线程t对x进行访问,判断当前是否为写访问,如果不为写访问则返回步骤二,否则遍历并分析WCx中线程u对x的历史访问信息直到最后一个元素,即如果WCx[u]中线程u的时间戳与当前线程t的时间戳VCt[u]不满足Happens-before关系,且t目前获得的锁集与WCx[u].LockSet交集为空集,则报告写-写类型数据竞争错误,进入步骤六;
步骤六:判断x当前是否处于读共享状态,如果处于读共享状态则判断读向量时钟Rx与当前线程t是否满足Happens-before关系,如果满足则报读-写类型数据竞争错误并删除Rx,否则进入步骤七;
步骤七:遍历并分析RCx中线程u对x的历史访问信息直到最后一个元素,即如果RCx[u]中线程u的时间戳与当前线程t的时间戳VCt[u]不满足Happens-before关系,且t目前获得的锁集与RCx[u].LockSet交集为空集,则报告读-写类型数据竞争错误,进入步骤八;
步骤八:判断WCx最后一个元素的epoch与t的epoch是否相等,如果相等则更新最后一个元素的LockSet集合;否则判断是否为满队,如果是满队状态则删除队首元素并将当前的访问信息加入到WCx中,否则直接将当前访问信息加入到RCx;
步骤九:判断终止条件,程序P是否执行完毕,如果P执行完毕,则输出数据竞争检测报告;否则,返回步骤二。
附图说明
附图1为一种自适应轻量级动态混合数据竞争检测方法的流程图。
附图2为不同动态数据竞争检测方法检测出的平均数据竞争数量对比图。
附图3为不同动态数据竞争检测方法平均内存开销对比图。
具体实施方式
以经典Java基准程序“raytracer”的数据竞争检测为例,结合附图1对本发明提出的一种自适应轻量级动态混合数据竞争检测方法的具体实施方式进行说明。
步骤一:针对一个Java并发程序raytracer,在不影响raytracer动态执行过程中,动态数据竞争检测器为每个共享变量x分别维护两个长度为Q_LEN=6的读队列RCx和写队列WCx,RCx和WCx均采用先入先出原则以缓存机制存储各线程对x的读访问信息和写访问信息,访问信息以<epoch,LockSet>形式存放,用来表示线程t的线程编号、访问时间戳和当前线程所持有的锁集合,其中epoch表示为[email protected],意为线程t的当前时间戳为c;
步骤二:当线程2对共享变量checksum1进行访问,判断当前是否为读访问,如果不为读访问则进入步骤五;否则首先判断当前checksum1是否已经处于读共享状态,如果是读共享状态则更新读向量时钟Rx为线程2的时钟向量VCt;否则去判断2当前读访问与RCx最后一个元素存放的读访问是否构成并发访问状态,如果是则动态数据竞争检测器自动切换为读向量时钟Rx来记录读访问历史,进入步骤三;
步骤三:遍历并分析WCx中线程u对checksum1的历史访问信息直到最后一个元素,即如果WCx[u]中线程u的时间戳与当前线程2的时间戳VCt[u]不满足Happens-before关系,且线程2目前获得的锁集与WCx[u].LockSet交集为空集,则报告写-读类型数据竞争错误,进入步骤四;
步骤四:判断RCx最后一个元素的epoch值与线程2的epoch值是否相等,如果相等则更新最后一个元素的LockSet集合;否则判断是否为满队,如果是满队状态则删除队首元素并将当前的访问信息加入到RCx中,否则直接将当前访问信息加入到RCx;
步骤五:线程2对checksum1进行访问,判断当前是否为写访问,如果不为写访问则返回步骤二,否则遍历并分析WCx中线程u对checksum1的历史访问信息直到最后一个元素,即如果WCx[u]中线程u的时间戳与当前线程2的时间戳VCt[u]不满足Happens-before关系,且线程2目前获得的锁集与WCx[u].LockSet交集为空集,则报告写-写类型数据竞争错误,进入步骤六;
步骤六:判断checksum1当前是否处于读共享状态,如果处于读共享状态则判断读向量时钟Rx与当前线程t是否满足Happens-before关系,如果满足则报读-写类型数据竞争错误并删除Rx,否则进入步骤七;
步骤七:遍历并分析RCx中线程u对x的历史访问信息直到最后一个元素,即如果RCx[u]中线程u的时间戳与当前线程2的时间戳VCt[u]不满足Happens-before关系,且线程2目前获得的锁集与RCx[u].LockSet交集为空集,则报告读-写类型数据竞争错误,进入步骤八;
步骤八:判断WCx最后一个元素的epoch值与线程2的epoch是否相等,如果相等则更新最后一个元素的LockSet集合;否则判断是否为满队,如果是满队状态则删除队首元素并将当前的访问信息加入到WCx中,否则直接将当前访问信息加入到RCx;
步骤九:判断终止条件,程序raytracer是否执行完毕,如果raytracer执行完毕,则输出数据竞争检测报告;否则,返回步骤二。例如,程序raytracer执行完毕后,输出的数据竞争检测报告为:
通过以上过程可以实现一种自适应轻量级动态混合数据竞争检测方法,检测流程图如图1所示,针对基准程序“raytracer”,使用Eraser方法、Djit+方法与本发明中的方法分别进行10次实验,图2是10次实验中检测出来的数据竞争数量平均值,图3是10次实验中各检测方法平均内存开销。从图2与图3可以看出,本方法检测出数据竞争数量与Djit+相当且平均内存开销下降了40%,相较于Eraser方法误报率降低了88.9%。本方法以低开销有效地检测数据竞争,可以作为一种动态数据竞争检测新方法。