跳到主要内容
版本:release

延迟/异步调用表达式

语法

描述

延迟调用表达式用于将一个函数调用送入延迟调用队列中,默认情况下,GS 会在后台创建一定数量的协程以执行这些调用。

延迟调用表达式的值是一个 future 对象(/builtin/future.gs),调用方可以使用此对象的 wait 方法等待调用完成并获取调用结果。 不应当使用除了 future 以外的方法,与延迟调用任务进行同步。

默认情况下,默认的延迟调用管理器将为(在有需要时)每个域创建一个队列;所有延迟调用的函数将根据函数期待的域,被分配到相应的队列中。

指定在对象所在域上调用

当尝试调用一个 parallel 方法时,可以在 @ 后面跟随一个变量,该变量应当是一个 object 或是 nil,如果是 nil,则如同指示在 当前域上执行;否则如果指定了对象,无论该对象是不是 parallel 的,都将尝试在该对象所在的域上执行该方法:

object obj = ...; // 某个对象
@obj:some_parallel_method(...); // 在 obj 所在的域上调用 some_parallel_method

缺陷

任何情况下,一个队列只有一个协程负责处理。这意味着在延迟调用的函数处理期间,继续向同一域中发起的延迟调用函数不会被执行——直到之前的函数都被处理完成; 这也意味着,尝试在延迟调用的函数中,发起并等待对同一域的延迟调用,将会导致死锁:

这一问题已知,正在讨论如何处理

// 这是一个错误示范
void baz()
{
}
void bar()
{
object future = @baz();

future.wait(); // 死锁!
writeln("Never be here"); // 永远不会执行到这里
}
void foo()
{
@bar();
}

foo();

示例

int foo(int x)
{
writeln("foo called with ", x);
return x * 2;
}
object future = @foo(42); // 延迟调用 foo(42)

writeln("Doing other things...");

int result = future.wait(); // 等待 foo(42) 执行完成,并获取

writeln("Result from foo: ", result);