简单聊聊并发编程

近期在看 Golang 相关的资料,虽然这门语言的类型后置让我这个 C 出身的人感到很难受,但是 Go 的种种特性确实让我眼前一亮。其中特别是并发,在云计算大数据如火如荼,分布式计算热火朝天的今天,这个特性让 Go 语言一下成为了明星语言。并发编程是面向对象编程中一种最合适的程序控制方式,因为在现实世界中,各个对象的各种操作都是并发的,其间通过消息传递来进行数据同步。

所以我们今天就来简单聊聊并发编程。

我们先了解一些并发编程中的概念:

1.延续性

并发编程中最关键的一个概念就是延续性(Continuation),这是一种对程序控制流程/状态的抽象表现形式。 延续性以数据结构的形式表现了程序在运行过程中某一点的计算状态,相应的数据内容能被编程语言访问并且不会被运行时环境所隐藏掉。
延续性包含了当前程序的栈以及当前运行的位置。一个延续的实例可以在将来被用作控制流,被调用时它从所表达的状态开始恢复执行。

延续性,其实就是一种函数调用机制。我们最常见的函数调用方法是使用堆栈,采用 Activation record 或者叫 Stack frame 来记录从最顶层函数到当前函数的所有 context 。一个 frame/record 就是一个函数的局部上下文信息,包括所有的局部变量的值和SP,PC指针的值。函数的调用前往往通过 push 来保存 context 信息,函数结束调用退出时则是取消当前的 record/frame,并恢复到上一个调用者的 record/frame 。这是一种后入先出的方式,上层函数需要获得下层函数返回的数据才能完成,因此你需要从顶层函数一层一层的往下调用,一直到最底层函数完成后,再逐层 return 依次完成。C/BASIC/PASCAL以及我们熟知的大部分语言就是采用这种方式。

而延续调用,不采用堆栈来保存上下文,而是把这些信息保存在 continuation record 中。这些 continuation record 和堆栈的 activation record 的不同,并不采用后入先出的堆栈存储方式,而是以节点的形式存放在树或者图中,从一个函数调用另一个函数就等于给当前节点生成一个子节点并系统寄存器移动到这个子节点上。
这样的好处是什么,就是我们不需要按照线性的顺序来完成函数,我们完全可以自由的在不同的节点间进行跳转,不需要像堆栈一样一层一层的 return。这里的 return 更像是一个带参数的 goto。
Continue Reading…

Python 入门篇 – 函数

函数

函数是 重用 的程序段。它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。这被称为 调用

函数定义

Python中,函数通过def关键字定义。def关键字后跟一个函数的 标识符 ,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。
例子:

输出结果显而易见:

Continue Reading…

Python 入门篇 – 控制流

在我们平时所写的程序中,总有一系列的语句,Python总是忠实的按照它们的顺序执行它们。如果要改变语句流的顺序,我们就要用到控制流。
说控制流可能很陌生,但是如果说具体来说就是if/for/while,你一定倍感亲切!

if

if是条件检验语句, 如果条件为真,我们运行一块语句(称为 if-块 ), 否则我们处理另外一块语句(称为 else-块 )。 else从句是可选的。

上面是一个最简单的有效if语句,注意if语句的结尾处包含一个冒号,我们通过它告诉Python下面跟着一个语句块。我们使用了缩进层次来告诉Python每个语句分别属于哪一个块。这就是为什么缩进在Python如此重要的原因。

上面的例子稍微复杂了点,但是还是很容易理解。
其中,我们用到了elif从句,用来做多条件选择。
elif和else从句都必须在逻辑行结尾处有一个冒号,下面跟着一个相应的语句块,包括正确的缩进。

同时也可以在一个if块中使用另外一个if语句,这被称为嵌套的if语句。

在这里还要注意的一点是:在Python中没有switch语句。但是你可以使用if..elif..else语句来完成同样的工作,或者使用Python中的字典。
Continue Reading…