zoukankan      html  css  js  c++  java
  • TLA+和并发系统正确性验证

    TLA+介绍

    TLA+(WIKI官网)是一门领域特定语言,主要用于数理逻辑计算和并发系统的正确性验证。TLA+中的TLA代表的是“行为时序逻辑(Temporal Logic of Actions)”,Action 是纯函数;“+”代表“Data Logic”。这是由 Dr. Lamport所提出的学说,他也因此获得了2013年图灵奖。Lamport在分布式计算和并发系统领域研究40多年,发布了180多篇高价值论文,是有志于此领域的必读材料。官网提供了大量的学习资源,另外Hillel Wayne写了一个很棒的入门教程

    TLA+利用高中或者大学学到的一些简单的数学知识(时序逻辑和数据逻辑),就可以发现程序中的错误,而这些错误用计算机来跑很长时间也可能不会发现。

    作为一门领域特定语言,TLA+语法简单,基础数据对象只有Set、Tuple、Function(这并不是其他语言中的函数,可以理解成Python的Dict或Java的hashmap)几种。剩下的语法都是数学逻辑知识,不过这也是其中最困难的部分,就是用抽象的思维来思考,用数学的方式来思考。数学本身不会让程序运行得更有效率,但能让程序更逻辑严谨。TLA+已在航空航天、微软、亚马逊等实际系统中起到关键作用。

    此外,为了便于使用,Lamport开发了PlusCal语言。PlusCal语言风格与C/Pascal语言类似,对传统语言出身的软件工程师对更加友好。在TLA+开发集成环境(TLA+ Toolbox)中,PlusCal会自动翻译成TLA+并运行。

    本文不尝试讲解TLA+和PlusCal基础语法和设计方法,因为这方面官网提供了语言讲解、教学视频、代码示例、cheatsheet等等丰富资源。本文主要想通过2个示例来展示TLA+的优雅和强大,让大家感受到TLA+的魅力所在。

    TLA+应用示例

    看下面这题,如果用TLA+来解题,应该该如何实现?

    在电影“虎胆龙威3-纽约大劫案”中,布鲁斯·威利斯和杰里米·艾恩斯遇到这样一个难题:给他们一个3加仑小壶和一个5加仑的大壶,要求在5加仑大壶里准确装入4加仑的水。

    本质上,TLA+(行为时序逻辑)描述的是一个状态机,每一个时序(Temporal Logic)下都是一个特定状态(action),状态的跳变只依赖于自身(即纯函数的含义)。

    本题中,状态机初始状态为小壶和大壶都为空;此后存在6种状态:小壶倒空、大壶倒空、小壶倒满、大壶倒满、小壶倒入大壶、大壶倒入小壶,状态机的下一个状态必为这6个状态中的一个。把如上分析转化为TLA+描述(如下):

    设置不变量(invariant):big = 4, TLA+会遍历所有状态可能性,并找到答案(如下):

    START(大壶水为0加仑)->{big:0,small:0} (初始状态)-> {big:5, small:0}(倒满大壶)-> {big:2, small:3}(大壶导入小壶)-> {big:2, small:0}(倒空小壶)-> {big:0, small:2}(大壶倒入小壶)-> {big:5, small:2}(倒满大壶)-> {big:4, small:3}(大壶导入小壶)->END(大壶水为4加仑)

    并发系统设计正确性验证

    cache = {}
    def increment(id):
        x = cache.get(id, None)
        if x is None:
            x = database.read(id)
            cache[id] = x
        
        x = x + 1
        database.write(id, x)
        cache[id] = x
    

    上面一段Python代码,increment功能为对数据库(database)的一个字段值加一后再存入数据库中,为了优化数据库的读效率,在数据库上加了一层缓存(cache)。

    在并发环境下,这段代码实现是有问题的,你能看的出来么?如何证明或验证此并发程序的正确性?

    把上面的python代码转成PlusCal描述,代码实现如下:

    所谓正确性验证,用数学的语言描述就是保证不变性。本例的一个不变性就是要保证数据库的一致性,换句话说,如果有N个进程并发执行increment(id),其值应该增加N。用TLA+描述如下:

     DBConsistent == (A i in 1..N: pc[i] = "Done") => database = N

    运行可见不变量DBConsistent遭违反(如下图),也证明了此并发程序存在bug。而且在Error-Trace中给出了违例的详细步骤和原因:如果1个进程A已执行完(Done)时,另一个进程B执行到状态t3,此时B进程中的x为0,但实际上数据库(database)和cache中的值已经为1了。

  • 相关阅读:
    第三章 Jenkins参数及web项目
    第二章 Jenkins的详细介绍
    第一章 Git+Gitlab介绍和安装
    第二章 Centos7下Airflow2.1.0安装
    第一章 Airflow基本原理
    第五章 Pinpoint-Apm常见报错
    第四章 Docker方式安装 Pinpoint
    数论练习
    CF练习
    矩阵乘法
  • 原文地址:https://www.cnblogs.com/wahaha02/p/7240337.html
Copyright © 2011-2022 走看看