Page 48 - 《软件学报》2021年第6期
P. 48

1622                                     Journal of Software  软件学报 Vol.32, No.6,  June 2021

         3.2   基于可覆盖性判定的数据竞争检测
             程序中关于同一个共享变量的两条读/写或者写/写操作,如果它们在执行顺序上存在先后依赖关系,则不
         会产生数据竞争;反之,若他们之间存在并发关系,则会导致数据竞争.由此一来,可以对程序的 Petri 网模型进行
         分析,判别两个操作对应的变迁是否在某些状态下具有并发关系.实际上,对于任意的两个变迁 t 和 t′,我们只需
                                              •
                                           •
                                                           •
                                                         •
         要判定是否存在一个可达标识 M,使得 M≥ t+ t′,即判定标识 t+ t′的可覆盖性.



























                              Fig.9    Java source code (left) and its Petri net model (right)
                                图 9   Java 程序源码(左)与其对应的 Petri 网模型(右)
             考虑图 9 所示的例子,其中,读共享变量 System.out.println(x)与写共享变量 x=2 之间未加同一把锁,会发生数
         据竞争.共享变量 x 的写操作 x=2 对应变迁 t9,读操作 System.out.println(x)对应变迁 t11,判定数据竞争只需验证
         目标标识{p8,p11}的可覆盖性.
             程序 Petri 网模型的反向展开流程见表 2.
             不难发现,Mark([e9])={ps},故目标标识{p8,p11}是可覆盖的,两个读写操作对应的变迁可以并发,程序存在
         潜在的数据竞争.
             本节构建了 Java 并发程序的 Petri 网模型,将数据竞争检测转化为验证相关变迁的可覆盖性,并结合实例展
         示了反向展开算法在数据竞争检测上的应用.然而,本文仅给出了 Java 多线程程序的 Petri 网建模方法,并没有设
         计实际的建模工具.在实际应用中,可以考虑使用 Soot               [30] 对 Java 并发程序自动化建模.Soot 是一款 Java 字节码
         分析优化框架,可以将 Java 源码转换为 Jimple 中间代码进行分析.比如:可以借助 JInvokeStmt 分析线程的启动
         与合并,以及各种函数调用;借助 JEnterMonitorStmt 与 JExitMonitorStmt 分析锁的申请与释放;借助 JIfStmt 与
         JGotoStmt 分析程序中的分支与循环.篇幅所限,我们将在后续工作对此展开研究.

         4    实验评估

             本节将通过实验对比启发式反向展开与 directed unfolding           [17] (一种同样采用了启发式技术的正向展开)在
         Petri 网可覆盖性问题上的效率.本文将通过事件总数及运行时间评估算法效率.实验所用的基准库包含 415 组
   43   44   45   46   47   48   49   50   51   52   53