std.task
タスクとチャネル。async も await も無く、どの関数も上から順に読める。 task f() で別の流れとして走らせ、parallel { } でまとめて待つ。 task・parallel・channel を使うだけなら import は省ける。
func slow() -> int { sleep(0.05); return 42; }
var t = task slow();
print("先に進める");
print(t.wait()); // 42
task.yield task.count task.channel Task.wait Task.wait_timeout Task.done Task.cancel Task.id channel.send channel.recv channel.try_recv channel.close channel.len
関数
- task.yield() → void¶
-
待ちが無くても、ほかのタスクに順番を譲る。
長い計算を回すタスクは、ときどき呼ぶと全体が詰まらない。
func heavy() -> int { var sum = 0; for var i in range(1000) { sum = sum + i; task.yield(); } return sum; } var t = task heavy(); print(t.wait()); // 499500
- task.count() → int¶
-
いま走っているタスクの数。
print(task.count() >= 0); // true
- task.channel<T>() → channel<T>¶
-
値を受け渡す待ち行列を作る。
オーバーロード:
task.channel<T>(capacity: int) -> channel<T>var ch = channel<int>(4); _ = ch.send(1); print(ch.recv() ?? -1); // 1
Task<T>
task f() が返す値。T は f の戻り値の型。
- Task.wait() → T¶
-
終わるまで待って、戻り値を受け取る。
func slow() -> int { sleep(0.05); return 42; } var t = task slow(); print(t.wait()); // 42
- Task.wait_timeout(t: Duration) → T?¶
-
時間を区切って待つ。間に合わなければ none。
import std.time; func slow() -> int { sleep(1.0); return 42; } var t = task slow(); print(t.wait_timeout(time.seconds(0.05)) ?? -1); // -1(間に合わない) t.cancel();
- Task.done() → bool¶
-
終わっているか。待たない。
func slow() -> int { sleep(0.05); return 1; } var t = task slow(); while !t.done() { sleep(0.01); } print(t.done()); // true
- Task.cancel() → void¶
-
取り消しを頼む。すぐには止まらず、待っている関数が次に見たときに終わる。
func slow() -> int { sleep(1.0); return 1; } var t = task slow(); t.cancel(); print("取り消しを頼んだ");
- Task.id() → int¶
-
見分けるための番号。
func slow() -> int { return 1; } var t = task slow(); print(t.id() >= 0); // true
channel<T>
タスクの間で値を受け渡す待ち行列。
送り手は何個でもよく、受け取るのは1つのタスク。コピーしても同じ待ち行列を指す。
- channel.send(v: T) → Result<void>¶
-
送る。ためられないときは、空くまで待つ。
var ch = channel<int>(2); print(ch.send(1).ok()); // true
- channel.recv() → T?¶
-
受け取る。何も無ければ届くまで待つ。閉じられていれば none。
func producer(ch: channel<int>) { for var i in range(3) { _ = ch.send(i); } ch.close(); } var ch = channel<int>(4); task producer(ch); while var v = ch.recv() { write(v); } // 012 print("");
- channel.try_recv() → T?¶
-
待たずに受け取る。何も無ければ none。
var ch = channel<int>(2); print(ch.try_recv() ?? -1); // -1(まだ何も無い) _ = ch.send(7); print(ch.try_recv() ?? -1); // 7
- channel.close() → void¶
-
閉じる。待っている受け手には none が返る。
var ch = channel<int>(1); ch.close(); print(ch.recv() ?? -1); // -1
- channel.len() → int¶
-
たまっている件数。
var ch = channel<int>(4); _ = ch.send(1); _ = ch.send(2); print(ch.len()); // 2