Table of Contents

コルーチン入門

1. 概要

1.1 ルーチンとは

note:routine-automaton.png

1.2 コルーチンとは

note:coroutine-automaton.png

コルーチンは明らかに状態を持つが,果たしてルーチンと言ってしまっていいのだろうか...

2. 利点

2.1 同時処理の2つの方法

note:concurrency-vs-parallelism.png

  • 並行処理は,消費リソースが少なく,全タスク完遂までの時間が長い
  • 並列処理は,消費リソースが多く,全タスク完遂までの時間が短い

2.2 スレッドの性質

note:thread-architecture.png

2.3 スレッドの問題

  • データ競合(data race)は,あるルーチンが書き込み中に,他のルーチンが読み書きを行うことで,共有リソースが不正な状態をとる,あるいはそのように読み込まれてしまう現象.
  • 競合状態(race condition)は,あるルーチンの振る舞いの正しさが,他ルーチンとの実行順序や実行タイミングに依存する状態.

2.4 コルーチンによる解決

note:coroutine-concurrency.png

  • スレッドでは,他ルーチンの影響を受けないことが保証される最小の命令単位は,マシンコードにおける1命令
  • コルーチンでは,最小の命令単位は,中断(yield)を用いてコルーチンの実装者が自由に決めることができる

コルーチンを使った並行処理は,green thread / userland thread / fiber などと呼ばれることもある.

3. 実装方法

3.1 コルーチンの実装

3.2 コルーチンを使った並行処理の実装

note:coroutine-concurrency-sequence.png

  • タスクキューは,スレッドにおけるOSのスケジューラと同等の役割を担っている
  • ただし,スケジューラとは異なり,タスクキューはコルーチンを中断させることはできない
    • コルーチンが中断される時は,コルーチン自らが中断した時だけである
    • これにより,意図しないタイミングでのルーチンの同時実行を防ぐことができる
  • また,スケジューラよりも明らかに軽量,かつ,高速である
    • スケジューラは,何百とあるスレッドの優先度や,属するプロセスの優先度,権限などを鑑みて次に処理するスレッドを決定し,スレッド切り替えまで行っている
    • 対して,タスクキューはただ単に受け取ったタスクを順番に実行するだけである

タスクキューのタスクに対して,発火時間プロパティを持たせることで,JavaScriptのsetTimeoutのようなことが可能になる.その場合,タスクキューの実体は,発火時間を優先度とする優先度付きキューになり,発火時間を過ぎていないタスクだけが残った時は[最も直近の発火時間まで,あるいは,新しいタスクを受け取るまで]sleepする.

std::priority_queueが輝く貴重な瞬間