Actor是Pony的并发模型,一个Actor就是一个线程,Pony将创建线程变得简单,但也使安全并发的语法变得复杂。
用关键字actor声明一个Actor。一个Actor很像类,但一个Actor还可以有行为(Behavior)。行为用be关键字定义,它就像一个永远返回空值(None)的函数.但官网上举出了它与函数的区别:function is synchronous, and behavior is asynchronous.
例:
actor Hello
let _name: String
let _env: Env
new create(name': String, env': Env) =>
_name = name'
_env = env'
be print_name() => _env.out.print(_name)
fun _final() => None
因为Hello有create函数,所以我们要实例化后才能使用。Actor实例化与类的实例化无异。
当没有create函数时,我们可以直接通过actor名去调用行为或方法:
actor Hello
var _name: String = "Name"
be print_name(env: Env) => env.out.print(_name)
fun _final() => None
actor Main
new create(env: Env) =>
Hello.print_name(env)
(博主认为,类也是这样,或许没有了构造方法,类就等于静态类,再如果没有字段,这个类就算是primitive)
例子原地址:https://github.com/ponylang/ponyc/blob/master/examples/mailbox/main.pony
use "collections"
actor Mailer
be ping(receiver: Main, pass: U32) =>
for i in Range[U32](0, pass) do
receiver.pong()
end
actor Main
var _env: Env
var _size: U32 = 3
var _pass: U32 = 3
var _pongs: U64 = 10
new create(env: Env) =>
_env = env
start_messaging()
be pong() =>
_pongs = _pongs + 1
_env.out.print(_pongs.string())
fun ref start_messaging() =>
for i in Range[U32](0, _size) do
Mailer.ping(this, _pass)
end
首先重申一下,以下划线开头的量或函数,都是私有的,意思是外部不能调用。
因为行为是并发的,所以,当Mailer的ping行为运行时,Main的pong行为也在运行,也就是说,两个线程在同时运行。所以,如果在create函数里,无论怎么输出_pongs,都会显示为10,而在pong行为中,输出的则会是一串数字。这就是并发。(请注意其中的数据传输,之后的教程里我们会遇见reference type system就是拿来处理并发过程中的数据问题的)
Main线程调用了Mailer.ping,因此,启动了Mailer线程,Mailer线程里的ping行为又调用了Main的pong行为。因为有两个循环,所以pong行为会被调用_size * _pass次,
啥叫顺序性?答曰:Sequential!Pony用这种性质使得我们从“锁(Lock)”的需要中解放出来。记住,每一个Actor一次只执行一个行为(behavior)。也就是说,你不必担心并发性会搞砸你的代码。
actor Main
new create(env: Env) =>
call_me_later(env)
env.out.print("This is printed first")
be call_me_later(env: Env) =>
env.out.print("This is printed last")
In the example below, the
Main
actor calls a behaviourcall_me_later
which, as we know, is asynchronous, so we won’t wait for it to run before continuing. Then, we run the methodenv.out.print
, which is also asynchronous, and will print the provided text to the terminal. Now that we’ve finished executing code inside theMain
actor, the behaviour we’ve called earlier will eventually run, and it will print the last text.
每一个Actor就是一个线程,重要的是他们可以并发!附上官网相关教程地址:https://tutorial.ponylang.org/types/actors.html。
我们下次见!欢迎加入Pony语言QQ群:261824044!